Saturday, 30 May 2015

Java Constructors

It is very common requirement to initialize an object immediately after creation. We can define instance methods for this purpose but they have to be invoked explicitly. Java has a solution for this requirement. Java allows objects to initialize themselves when they are created using constructors.

The syntax of the constructors is very similar to that of instance methods. They have the same name as the class and do not have any return type. This is because the implicit return type of a class’s constructor is the class itself. Constructors can be overloaded just like methods.

When operator new is used to create an instance/object of a class, JVM allocates memory for the object, then initializes the instance variables to their default initial values, and then calls the appropriate constructor to initialize the instance variables.

We have not explicitly used constructors so far. But every class has a default constructor that does not take any argument and its body does not have any statements. The compiler generates the default constructor automatically. The compilers stops generating default constructor as soon as you add your own constructor.

Note: The name constructor is a bit confusing. It appears as if the purpose of the constructor is to create an object/instance. The object is created and instance variables and static variables are initialized to their default initial values before constructor is called. So the purpose of the constructor is to initialize the instance variables after the object has been created.

1. Default Constructor

Example: The following program does not define any constructor so it uses the default constructor, which does not take any parameters.

1 class Box

2 { float width;

3 float height;

4 float depth;

5 public static void main(String args[])

6 { Box b = new Box();

7 float volume = b.width * b.height * b.depth;

8 System.out.println("Volume = " + volume);

9 }

10 }

The compiler would automatically generate the following default constructor while compiling the above program:

Box()

{

}

The output of the above program will be 0 (Zero) as constructor is not doing any initialization and default initial value of float type instance variables is 0 (Zero).

2. No Argument Constructor

You can replace the default constructor with your own no argument constructor. This will allow you to initialize the instance variables to any value.

Example: The following program defines a no argument constructor, which is called immediately after creation of object.

1 class Box

2 { private double width, height, depth; //data hiding

3 double volume()

4 { double vol = width * height * depth;

5 return vol;

6 }

7 Box() // No argument constructor

8 { System.out.println("Initializing Box");

9 width = 10;

10 height = 10;

11 depth = 10;

12 }

13 }

1 class BoxDemo7

2 { public static void main(String args[])

3  { Box b1 = new Box();

4 Box b2 = new Box();

5 double volume = b1.volume();

6 System.out.println(volume);

7 volume = b2.volume();

8 System.out.println(volume);

9 }

10 }

The user-defined no argument constructor would be called immediately after the object creation and would initialize the values of the instance variables width, height and depth to 10. Thus the output of the above program would be 1000 instead of 0 (Zero).

3. Parameterized Constructors

The no argument constructor defined in the previous example is not of much use as it always initializes with the same value. A constructor, which can take parameters, will be more useful.

this keyword:

Sometimes a method will need to refer to the object that invoked it. To allow this, Java defines this keyword. It can be used inside any method to refer to the current object. That is, this is always a reference to the object on which the method was invoked. You can use this anywhere a reference to an object of the current class’s type is permitted. To better understand what this refers to, consider the following example.

Instance Variable Hiding

As you know, it is illegal in Java to declare two local variables with the same name inside the same or enclosing scopes. Interesting, you can have local variables, including formal parameter to methods, which overlap with the name of the class’s instance variables. However, when a local variable has the same as an instance variable, the local variable hides the instance variable.

This is why width, height, and depth were not used as the names of the parameters to the Box() constructor inside the box class. If they had been, then width would have referred to the formal parameter, hiding the instance variable width.

While it is usually easier to simply use different names, there is another way around this situation. Because this lets you refer directly to the object, you can use it to resolve any name space collisions that might occur between instance variables and local variables.

Example: The following program defines a parameterized constructor, which is used for initializing the object.

1  class Box

2  { private double width, height, depth; //data hiding

3 double volume()

4 { double vol = width * height * depth;

5 return vol;

6 }

7 Box(double w, double h, double d) //Parameterized constructor

8 { System.out.println("Initializing Box");

9 width = w; height = h; depth = d;

10 }

11 /* Box(double width,  double height, double depth)  //Parameterized constructor

12 { System.out.println("Initializing Box");

13 this.width = width;

14 this.height = height;

15 this.depth = depth;

16 }*/

17  }

1   class BoxDemo8

2  { public static void main(String args[])

3   { Box b1 = new Box(10,20,15);

4 Box b2 = new Box(3,6,9);

5 double vol;

6 double volume = b1.volume(); System.out.println(volume);

7 volume = b2.volume(); System.out.println(volume);

8 }

9  }

The parameterized constructor allows you to initialize the box with any dimensions.

4. Overloading Constructors

It is possible to overload the constructor just like methods. For example, the constructor of class Box can be overloaded to initialize different types of boxes. If we have a cube then we need to pass just one argument as all the sides of the cube would be of same dimension.

Example: The following program makes use of overloaded constructor to create and initialize the different type of boxes.

1  class Box

2  { private double width, height, depth; //data hiding

3 double volume()

4 { double vol = width * height * depth;

5 return vol;

6 }

7 Box(double w, double h, double d)

8 { width = w; height = h; depth = d;

9 }

10 Box()

11 { width = -1; height = -1; depth = -1;

12 }

13 Box(double len)

14 { width = height = depth = len;

15 }

16 Box(Box ob)  // Copy Constructor

17 { width = ob.width; height = ob.height; depth = ob.depth;

18 }

19  }

1 class BoxDemo9

2 { public static void main(String args[])

3  { Box b1 = new Box(10,20,15);

4 Box b2 = new Box();

5 Box b3 = new Box(5);

6 Box b4 = new Box(b1);

7 double vol;

8 vol = b1.volume();

9 System.out.println(vol);

10 vol = b2.volume();

11 System.out.println(vol);

12 vol = b3.volume();

13 System.out.println(vol);

14 vol = b4.volume();

15 System.out.println(vol);

16 }

17 }

No comments:

Post a Comment