Transcripted Summary

There are some interesting details about how constructors work when inheritance is involved.

Let's explore by adding constructors to the Person and Employee classes.

When we create a new instance of the subclass, it's going to make a call to the superclass's constructor before it executes the subclass's constructor.



If we look at this Employee default constructor, we didn't explicitly define it, but remember, in Java it's already defined implicitly.



But let's go ahead and explicitly define these default constructors so that you can see how they work in inheritance. And I'm just going to have a print statement in each of these.

public class Employee extends Person {

    public Employee(){
        System.out.println("In Employee default constructor");
    }
}

And for the ‘Person` class we will add a similar print out line.

public class Person {
    public Person(){
        System.out.println("In Person default constructor");
    }
}

And I'm going to run this InheritanceTester class.



Notice, I made a call to the default constructor of Employee. However, the Person default constructor was called before the Employee default constructor. So, if we go inside this constructor, there's nothing here that explicitly says that we're going to go inside of the Person constructor. However, by us inheriting from the Person class, that constructor, that default constructor was called first.

And if we really think about it, it makes sense — we are inheriting from this class.

We want to make sure that everything is set up in this class, that it's constructed before we actually try to use anything in the base class.

Well, let's say we didn't want a call to the default constructor of the superclass, but maybe there was some other constructor that we wanted to be called first.

Let's go inside of Person and let's make another constructor that takes the name.

public Person(String name){
    System.out.println("In Person 2nd constructor. Name is set");
}

So, I've created the constructor, it takes the name, and it'll print out this statement — "In Person 2nd constructor. Name is set"

If we go inside Employee and we wanted that constructor to be called instead of the Person default constructor, then we can explicitly state that by using a call to super which will call into the constructor of the superclass.

If we call super without anything in the parentheses, this will call the default constructor of the Person class. However, if we wanted to call into any other constructors, we would just pass the required arguments.

public Employee(){
    super("angie");
    System.out.println("In Employee default constructor");
}

So, because Person has a constructor that takes a String, we can call into that by passing that String. So instead of calling the default, this will call into the 2nd one.

Let's run it.



Notice here, the default constructor was not called for the superclass. Instead, the 2nd constructor was called, and then the subclass's constructor.

Explicit Calls to Superclass Constructors Must Come First

Note that if you're going to make an explicit call to the superclass's constructor, then that call must be the very first line of the subclass's constructor.

If we were to try to move this line below the print statement, we get an error that's saying that super() must be the first statement.



Another interesting thing is that if the superclass does not have a default constructor, then the subclass must explicitly call one of its other constructors.

Let's take this super() call out of the Employee class, and let's go to the Person class and remove the default constructor.

If we go back to Employee, now we have an error saying there's no default constructor available in the Person class.



So again, by default, the subclass's default constructor is making an implicit call to the Person default constructor. And because Person does not have a default constructor, we get an error.

Visiting the Person class again, it doesn't have a default constructor because it's explicitly defined another constructor. And if you do this, you no longer get the default constructor for free from Java.

To fix this, we would have to make a call to one of the constructors that exists. So, we add back the super() and pass in the argument.


# Rules for Constructors in Inheritance



Just to reiterate the rules about constructors in inheritance:

  • A superclass's constructor is run before the subclass's constructor.

  • Explicit calls can be made to superclass's constructor from one of the subclass's constructors by using super().

  • Explicit calls to the superclass's constructor must be the first statement in the subclass's constructor.

  • If the superclass does not have a default constructor, the subclass must explicitly call one of its other constructors.



Resources