Java seems to be inconsistent in how class constructors and methods deal with inheritance.
Case 1 - Methods:
public class HelloWorld
{
public static void main(String[] args)
{
Bee b = new Bee();
b.foo();
}
}
class Insect {
public void foo() {
this.bar();
System.out.println("Insect foo");
}
public void bar() {
System.out.println("Insect bar");
}
}
class Bee extends Insect {
@Override
public void foo() {
super.foo();
System.out.println("Bee foo");
}
@Override
public void bar() {
System.out.println("Bee bar");
}
}
The above code outputs the following:
Bee bar
Insect foo
Bee foo
Notice the call to "this.bar()" in Insect's foo() method actually goes back and calls Bee's bar() method (instead of calling Insect's bar() method).
Case 2 - Constructors:
public class HelloWorld
{
public static void main(String[] args)
{
Bee i = new Bee(1);
}
}
class Insect {
public Insect(int size) {
this(size, 123);
System.out.println("Constructor: Insect size");
}
public Insect(int size, int height) {
System.out.println("Constructor: Insect size, height");
}
}
class Bee extends Insect {
public Bee(int size) {
super(size);
System.out.println("Constructor: Bee size");
}
public Bee(int size, int height) {
super(size, height);
System.out.println("Constructor: Bee size, height");
}
}
The above outputs the following.
Constructor: Insect size, height
Constructor: Insect size
Constructor: Bee size
Notice the call to "this(size, 123);" in Insect's constructor goes to Insect's 2nd constructor instead of bee's 2nd constructor.
So in summary, method calls go back to the subclass while constructor calls stay in the superclass. Can anyone explain why?
Beyond the correct information in the comments about methods being not the same as constructors - you are actually over-simplifying things.
You see, when you write constructors, you have to decide if you intend to use a "same class" constructor (when you use this()
) - or if you want to invoke a super class constructor (using super()
) instead. There is no middle ground here - you have to be explicit about this!
Keep in mind: the responsibility of a constructor is to initialize an object of the corresponding class. It can make a huge difference if you call this(whatever)
or super(whatever)
within your constructors.
The compiler can't know what you intend to do. Therefore you have to be explicit about the exact other constructor you want to be invoked.
And beyond that - it simply doesn't make sense to have polymorphism kick in here like this. You absolutely want that object initialization takes place as you expect it to happen. Because wrongly initialized objects for sure create problems later on.
Your idea of making constructors polymorphic basically means that you determine at runtime which constructor to invoke. But you already know that you are in class X, and that you have to initialize a new X object. There is nothing to gain from allowing polymorphism here. To the contrary - doing so would allow for very strange and bizarre problems that would be purely runtime only!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With