It is important to understand how constructors in the classes at various levels in a class hierarchy behave. The order in which the constructors are called and how the default constructors of the super-class are called is explained here.
Multi Level Default Constructors
class MultiLevelDefaultConstructors
{
public static void main(String arg[])
{
System.out.println("---------------");
A a = new A();
System.out.println("---------------");
B b = new B();
System.out.println("---------------");
C c = new C();
System.out.println("---------------");
}
}
class A
{
A() // LINE A
{
System.out.println("Created A");
}
}
class B extends A
{
B()
{
System.out.println("Created B");
}
}
class C extends B
{
C()
{
System.out.println("Created C");
}
}
OUTPUT---------------
Created A
---------------
Created A
Created B
---------------
Created A
Created B
Created C
---------------
DESCRIPTIONHere we have a created a hierarchy of classes, C
extending B
, which in turn extending from A
. We only defined the default constructors and included the print statements. As we can observe when a sub-class object is created, the super-class object is by default created. So when object of class B
is created both Created A and Created B are printed. Similarly when the object of class C
is created Created A, Created B and Created C are printed.
THINGS TO TRY
- Create a class
D
which extends from C
, and define the default constructor with a print statement.
- Remove the default constructor in class
A
at LINE A
, and add another constructor which takes one int
parameter. Observe the compilation error you get. Please note that we need to change the sub-class constructors, to pass the parameter to the newly created super-class constructor, otherwise it throws the compilation errors.
Multi Level Constructors
class MultiLevelConstructors
{
public static void main(String arg[])
{
System.out.println("---------------");
X x = new X(10);
System.out.println("---------------");
Y y = new Y(11, 21);
System.out.println("---------------");
Z z = new Z(12, 22, 32);
System.out.println("---------------");
}
}
class X
{
int i;
X(int i)
{
this.i = i;
System.out.println("Created X");
}
}
class Y extends X
{
int j;
Y(int i, int j)
{
super(i);
this.j = j;
System.out.println("Created Y");
}
}
class Z extends Y
{
int k;
Z(int i, int j, int k)
{
super(i, j);
this.k = k;
System.out.println("Created Z");
}
}
OUTPUT---------------
Created X
---------------
Created X
Created Y
---------------
Created X
Created Y
Created Z
---------------
DESCRIPTIONHere we have a created a hierarchy of classes, Z
extending Y
, which in turn extending from X
. When we observe the output we realize that when creating the sub-class object, the super-class constructor is called before the current constructor. So when object of class Y
is created both Created X and Created Y are printed. Similarly when the object of class Z
is created Created X, Created Y and Created Z are printed.
THINGS TO TRY
- Create a class
W
extending from class Z
, with member variable int l
and a constructor which takes i
, j
, k
, l
as parameters. Pass i
, j
, k
as parameters to the super-class (Z
) constructor.
The following observations can be made from the above two programs.
- The super-class constructor is always called before the current constructor. So in
C
's constructor, B
's constructor is called and in B
's constructor A
's constructor is called.
- When the super-class has a default constructor, it is not necessary to call it using the
super
keyword. It is automatically called as shown in the first program. The constructors for X
and Y
are called, when an object Z
is created.
- If a super-class contains two or more constructors, but one of them is a default constructor which does not take any parameters, then it is not necessary to call it using the
super
keyword. It will automatically call the default constructor.
class A
{
int i;
A(int i) // CONSTRUCTOR 1
{
this.i = i;
}
A() // CONSTRUCTOR 2 - DEFAULT CONSTRUCTOR
{
i = 100;
}
}
class B extends A
{
double j;
B(double j)
{
this.j = j;
// Works fine, calls the CONSTRUCTOR 2, which is the default constructor.
}
}
class C extends A
{
C(int i)
{
super(i); // Works fine as well, calls the CONSTRUCTOR 1.
}
}
- If a super-class contains two or more constructors and there is no default constructor, it is required that the sub-class constructor specifically call the required super-class constructor using
super
keyword.
class A
{
int i;
int j;
A(int i) // CONSTRUCTOR 1
{
this.i = i;
j = i;
}
A(int i, int j) // CONSTRUCTOR 2
{
this.i = i;
this.j = j;
}
}
class B extends A
{
double j;
B(double j)
{
// Causes Compilation error, since it does not know whether to call CONSTRUCTOR 1 or CONSTRUCTOR 2 and there is no default constructor
this.j = j;
}
}
class C extends A
{
C(int i)
{
super(i); // No error, works fine.
}
}