Frage

I read in scjp guide as following

In fact, you can't make a new object without invoking not just the constructor of the object's actual class type, but also the constructor of each of its superclasses!

For example

public class Person{

}

public class Employee extends Person{
   public Employee(){
}
}

I don't create a Person instance but it is legal.

Please explain for me, thank for your help.

War es hilfreich?

Lösung

Whenever you instantiate a subclass, it'll call your superclass' constructor first.

You can find more about this here: JSL §8.8.7

Person.java

public class Person {
    public Person() {
        System.out.println("Super class constructor called");
    }
}

Employee.java

public class Employee extends Person {
    public Employee() {
        System.out.println("Sub class constructor called");
    }
}

If you then instantiate your Employee:

Employee e = new Employee();

Output:

Super class constructor called

Sub class constructor called

Andere Tipps

What they actually mean is

  • When you are creating a subclass object, i.e. its constructor is getting called, then superclass constructor gets callued internall
  • This is because for the default no-argument constructor there is a default super() call to the superclass constructor.
  • This goes on like the class hierarchy until the Object class.

In fact, if you do not write a no-argument constructor in superclass then the subclass declaration will throw compiler error.

public class Super {

    public Super(int num){

    }
}

public class Sub extends Super {

}

Here, class Sub will not compile giving the error Implicit super constructor Super() is undefined for default constructor because it cannot find a no-argument constructor in super class as the default no-argument constructor i.e. provided by compiler will have an implicit call to super().

  • Compiler provides a default no arg constructor only if there is no other constructor defined
  • As we have explicitly defined Super(int num), we will have to exlicitly create no-arg constructor as follows.

      public Super(){
    
    }
    

First, you don't have to create a parent instance (Parent) to instantiate a child class (Employee). You must have understood wrong.

Invoking the constructor of the parent class doesn't mean to create a new parent instance object (you're not calling it with new, so no new instance is created). You are creating a child instance, and for this, you need to first invoke the parent's constructor because of inheritance. Imagine for example the parent class has private fields that must be initialized in the constructor (for example private final fields). This fields cannot be accessed from the child class, but they can be initialized from the parent class constructor. You need to initialize this fields in the child instance, and the only way is calling super().

In this case Person has a default contructor which is invoked by default, no need to explicitly call it.

But in case Person has no default constructor, you need to call it explicitly. For example:

public class Person{
    private final String name;
    public Person(final String name) {
        this.name = name;
    }
}

public class Employee extends Person {
   public Employee() {
   }
}

This will not compile. You need to modify Employee so it calls Person constructor explicitly. For example:

public class Employee extends Person {
   public Employee(final String name) {
      super(name);
   }
}

Superclass' nullary constructor is implicitly called.

Its because of constructor chaining:

First statement inside a any constructor by default is super();(This is a call to super class default constructor).

I don't create a Person instance but it is legal: thats because you have a default constructor in Person class. So Employee class constructor can actually invoke super class constructor. Person()

Bottom line, the current class in which you are declaring a constructor, all the constructor upto the base class should be accessible via super(). If not, you have to explicitly make them accessible by explicitly making a call via super with proper parameters.

You have encountered one of the oddities of java.

If you don't define any constructors, the default, or "no args", constructor is implicitly defined. It's like invisible code.

If you define any constructor, args or no args, the implicit default constructor goes away.

To further compound the mystery, the first line of any subclass constructor must be to call a constructor of the super class. If you don't explicitly call one, the no-args constructor is implicitly called.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top