A subclass inherits accessible data fields and methods from its superclass. Does it inherit constructors? Can superclass constructors be invoked from subclasses? This section addresses these questions and their ramification.
The discussion in §7.12, "The this Keyword," introduced the use of the keyword this as a surrogate to refer to the calling object. The keyword super refers to the superclass of the class in which super appears. It can be used in two ways:
To call a superclass constructor.
To call a superclass method.
The syntax to call a superclass constructor is:
super (), or super (parameters);
The statement super() invokes the no-arg constructor of its superclass, and the statement super(arguments) invokes the superclass constructor that matches the arguments . The statement super() or super(arguments) must appear in the first line of the subclass constructor and is the only way to invoke a superclass constructor.
Caution
You must use the keyword super to call the superclass constructor, and the call must be the first statement in the constructor. Invoking a superclass constructor's name in a subclass causes a syntax error. |
Note
A constructor is used to construct an instance of a class. Unlike properties and methods, the constructors of a superclass are not inherited in the subclass. They can only be invoked from the constructors of the subclasses, using the keyword super . |
A constructor may invoke an overloaded constructor or its superclass's constructor. If neither of them is invoked explicitly, the compiler puts super() as the first statement in the constructor. For example,
In any case, constructing an instance of a class invokes the constructors of all the superclasses along the inheritance chain. A superclass's constructor is called before the subclass's constructor. This is called constructor chaining . Consider the following code:
1 public class Faculty extends Employee { 2 public static void main(String[] args) { 3 new Faculty(); 4 }
5 6 public Faculty() { 7 System.out.println( "(4) Faculty's no-arg constructor is invoked" ); 8 } 9 } 10 11 class Employee extends Person { 12 public Employee() { 13 this ( "(2) Invoke Employee's overloaded constructor" ); 14 System.out.println( "(3) Employee's no-arg constructor is invoked" ); 15 } 16 17 public Employee(String s) { 18 System.out.println(s); 19 } 20 } 21 22 class Person { 23 public Person() { 24 System.out.println( "(1) Person's no-arg constructor is invoked" ); 25 } 26 }
In line 3, new Faculty() invokes Faculty' s no-arg constructor. Since Faculty is a subclass of Employee , Employee' s no-arg constructor is invoked before any statements in Faculty' s constructor are executed. Employee' s no-arg constructor invokes Employee' s second constructor (line 12). Since Employee is a subclass of Person , Person' s no-arg constructor is invoked before any statements in Employee' s second constructor are executed. Therefore, the output of creating an instance of Faculty is:
(1) Person ' s no-arg constructor is invoked (2) Invoke Employee ' s overloaded constructor (3) Employee ' s no-arg constructor is invoked (4) Faculty ' s no-arg constructor is invoked
Caution
If a class is designed to be extended, it is better to provide a no-arg constructor to avoid programming errors. Consider the following code: 1 public class Apple extends Fruit { 2 } 3 4 class Fruit { 5 public Fruit(String name) { 6 System.out.println( "Fruit's constructor is invoked" ); 7 } 8 } Since no constructor is explicitly defined in Apple , Apple 's default no-arg constructor is declared implicitly. Since Apple is a subclass of Fruit , Apple 's default constructor automatically invokes Fruit 's no-arg constructor. However, Fruit does not have a no-arg constructor because Fruit has an explicit constructor defined. Therefore, the program cannot be compiled. |
The keyword super can also be used to reference a method other than the constructor in the superclass. The syntax is like this:
super .method(parameters);
You could rewrite the printCircle() method in the Circle class as follows :
public void printCircle() { System.out.println( "The circle is created " + super .getDateCreated() + " and the radius is " + radius); }
It is not necessary to put super before getDateCreated() in this case, however, because getDateCreated is a method in the GeometricObject class and is inherited by the Circle class. Nevertheless, in some cases, as shown in the next section, the keyword super is needed.
Caution
You can use super.p() to invoke the method p() defined in the superclass. Suppose A extends B , and B extends C , and a method p() is defined in C . Can you invoke super.super.p() from A ? The answer is no. It is illegal to have such a chain of super s in Java. |