Java: Extending a Class that has a Constructor; the “super” Keyword

, ,

Here's a example of inheritance of a class that has a constructor.

Note: constructors are never inherited, only variables and methods are.

class B {
    B () {System.out.println("BBB");}
    int triple (int n) {return n*3;}
}

class C extends B {}

public class Inh {
    public static void main(String[] args) {
        C c = new C();
        System.out.println(c.triple(4));
     }
}

In the above code, C is subclass of B. So, C inherent B's methods. However, the special method B() is B's constructor, and it is not inherited because Java does not inherit constructors. In the “main” method, a instance of C is created, and the inherited method “triple” is called.

If you run the program, it will print “BBB” followed by “12”. It prints “BBB” because in Java, when a subclass is created, it automatically calls its parent's constructor (if the class itself does not define constructors).

Extending a Class that has Constructor with Parameters

Here's a example of extending a class that has a constructor with parameters.

The code won't compile and gives a mysterious message. See if you can fix it.

/* note: this code won't compile*/

class B {
    B (int n) {
        System.out.println("B's constructor called");
    }
}

class C extends B {
    C (int n) {
        System.out.println("C's constructor called");
    } 
}

public class Inh2 {
    public static void main(String[] args) {
        B b = new B(4);
        C c = new C(2);
     }
}

The error from javac 1.5 is:

Inh2.java:8: cannot find symbol
symbol  : constructor B()
location: class B
    C (int n) {
              ^
1 error

Answer below.


The problem has to do with the paradigm and language machineries of OOP and Java.

When creating a constructor of a class whose parent class has a non-default constructor (that is, having parameters), then in the definition of the constructor it must call the parent class's constructor, in the first line, using the “super” keyword. The “super” is a instance of the parent class.

The way this makes sense is that a object is potentially very complex, and each class's constructor may do many things to make sure that when a class is instantiated, the object is created and ready to go. Therefore, when subclassing a class, the constructor in the subclass should make a call to its parent class's constructor first, as to make sure every required initialization is done well. This is so because the subclass potentially has no idea what initializations the parent class must do. (the source code of parent class may not be available)

When a class does not define constructors, Java internally automatically has a constructor that does nothing. When extending such a class, no special thing needs to be done in the subclass's constructor because the parent class's constructor does nothing.

In our example, the class B has a user defined constructor. Therefore, Java did not create a do-nothing constructor for it. And, thus when we have a class C that extends B, the programer needs to call the constructor of B.

To fix the code above, add super(n); in the first line of the subclass's constructor.

If the class C does not call B's constructor, Java compiler automatically assumes that the user wants the no-argument constructor B(), and call it for you. But since Java did not internally create the no-argument constructor, therefore it gives the error of symbol not found.

Reference

Source docs.oracle.com

Source docs.oracle.com

blog comments powered by Disqus