-1

In this example I have a subclass with a blank constructor. In the superclass there is two constructors provided. When I execute the main in the code below, it turns out that it prints "I am the super constructor without parameter." My question is that, why the compiler ignores the blank constructor in the subclass? If I can accept this "ignorance", then I understand that the compiler will execute the default constructor of the subclass, which, in this case, is the one in the superclass with no parameter. Here is the subclass:

package extendisevil;

public class SubConstructorInherit extends ConstructorInherit {

  public SubConstructorInherit(String param) {

  }

  public static void main(String[] args) {

    SubConstructorInherit obj = new SubConstructorInherit("valami");

  }
}

And here is the super:

package extendisevil;

public class ConstructorInherit {

  public ConstructorInherit(String name) {
    System.out.println("I am the super constructor with String parameter: " + name);
  }

  public ConstructorInherit() {
    System.out.println("I am the super constructor without parameter.");
  }

}

Thank you for your help!

csakos
  • 1
  • 2

2 Answers2

7

Java is not ignoring the constructor of the subclass, java calls it. However, java has to also construct every superclass, and since you don't call a particular super-constructor in your subclasses constructor, java just defaults to the no-arg constructor. If you want to call any other constructor than the no-arg constructor in the parent-class, you can do this by calling super(/* args */);, this has to be the first statement in your constructor though:

class Parent {
    Parent() {
        System.out.println("Parent()");
    }
    Parent(String name) {
        System.out.println("Parent(String): " + name);
    }
}

class Child extends Parent {
    Child() {
        //calls "super()" implicitly as we don't call a constructor of Parent ourselfs
        System.out.println("Child()");
    }

    Child(String name) {
        super(name); //we explicitly call a super-constructor
        System.out.println("Child(String): " + name);
    }
}

new Child();
new Child("A Name");

Prints:

Parent()
Child()
Parent(String): A Name
Child(String): A Name

If a class doesn't provide a no-arg constructor but a constructor with arguments, a subclasses constructor has to call one of the given constructors explicitly.

tkausl
  • 13,686
  • 2
  • 33
  • 50
  • I'm nitpicking here, but we really shouldn't use the term `default constructor` in this case, a better name is `no-arg constructor`. The reason being, `default constructor` is the specific name for the auto-generated no-arg constructor classes get in the absence of any explicit constructors. – biziclop Jun 22 '16 at 14:02
  • You're right, edited it. – tkausl Jun 22 '16 at 14:03
  • Perhaps the use of implicit versus explicit would crystallize the explanation. – Grayson Jun 22 '16 at 14:06
  • Thank you for your help. I missed that java constructs every superclasses along with the subclass. Thanks again for the clear explanation. – csakos Jun 23 '16 at 08:26
1

The fact that the superclass has a parameter list with the same types is irrelevant - what if the string passed to the subclass has a totally different semantic meaning to the string passed to the superclass? (It's not clear why name and param mean the same thing)

If you need a particular non-zero-arg constructor to be invoked, it is better that you have to be explicit about passing the parameters to the super constructor (at the expense of a few more key strokes) rather than incorrectly assuming that a particular ctor should be invoked.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243