I think we already discussed this issue in this post here Inheritance in Java simple clarification
But since the example here is a bit simpler and the point i want to be clarified is different i´ll give it a shot.
First, the two classes to discuss:
public class SuperClass{
SuperClass() {
foo();
}
public void foo() {
System.out.println("Super.foo()");
}
public static void main(String[] args) {
SuperClass tn = new DerivedClass();
tn.foo();
}
}
public class DerivedClass extends SuperClass{
String i;
TrickyB() {
i = "aksjhdf";
}
public void foo() {
System.out.println("In derived.foo() --> " + i);
}
}
I (at least I think) understand the concepts of polymorphism and i know why DerivedClass.foo() is called when invoking
new DerivedClass();
I see an inconsistency here:
At the time we invoke the c´tor of DerivedClass the c´tor of the SuperClass is called implicitly (so to say as the first line of the Derived c´tor).
So in the Super c´tor, DerivedClass is not fully initialised, which makes working with this class useless.
This point is reflected in the output of this program
In derived.foo() --> null
In derived.foo() --> aksjhdf
The first line reflects my confusion:
Why is DerivedClass.foo() called? The object is not ready yet, so doing anything with it is nonsense in my eyes.
Can anyone explain the reasons to me. I think this absolutely counter intuitive.
BTW: I would have expected SuperClass.foo() to be called, since, as I said, it doesnt make any sense to work with an "unready" object.
On the other Hand: As I think of it. It doesn´t make any sense to me neither, that, while I´m in the c´tor of SuperClass, DerivedClass.foo() is called!
How would I call SuperClass.foo() in my case?
Why is DerivedClass.foo() called? The object is not ready yet, so doing anything with it is nonsense in my eyes.
No. The object has already been created. Constructors don't create objects, it just initializes them. The object is created by new operator here.
I would have expected SuperClass.foo() to be called
As already explained, it's not that object is not created. It's already been. And that invocation will call the overridden method. That is why you should never call overridden method from constructor. You'll see unexpected behaviour.
SuperClassdoes not know anything about any derived classes.
Well, it doesn't need to know. The fact that the method invocation invokes the derived class method has nothing to do with whether superclass knows about subclass or not. The actual method that will be invoked is decided at runtime, based on the actual object in picture. Since here, the object is of type DerivedClass, the method in the DerivedClass if present will be invoked.
How would I call SuperClass.foo() in my case?
You don't. That's the whole point. Go through the post that I linked for step-by-step explanation.
Unlike C++, Java sets the runtime type of the object at the time of allocation, before any constructor is run. This is why polymorphic behavior occurs during initialization.
This behavior can be useful sometimes, under controlled circumstances. In most cases, however, it's a good idea to avoid it, because you are leaking an uninitialized object to code that is external to your class (via the this reference in the virtual method). You should try only calling private (or final) methods from the constructor, whenever possible.
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