问题
I am testing some polymorphism in java and my code looks like the following:
class Base {
int value = 0;
public Base(){
System.out.println("Came Here And Value is: " + value);
addValue();
}
String addValue(){
System.out.println("Calling Bases' addValue and value is currently: " + value);
value += 10;
return "";
}
int getValue(){
return value;
}
}
class Derived extends Base{
public Derived(){
System.out.println("Calling Derived constructor and value currently is: " + value);
addValue();
}
String addValue(){
System.out.println("Came to Deriveds' addValue and value now is: " + value);
value += 20;
return "";
}
int getValue(){
return value;
}
}
public class MyClass {
public static void main(String [] args){
Base b = new Derived();
System.out.println(b.getValue());
}
}
So the thing here is, it prints 40 but I'm guessing that it should print 30. My thoughts are: new Derived first calls new Base, which calls addValue()
and (as addValue()
defined in Base adds up value by 10) value should be 10 at that time. then, Derived's addValue()
is called which makes value 30 (because addValue()
defined in Derived adds value up by 20). But instead, Base invokes it's child's addValue()
. Can someone explain what's happening?
回答1:
The misconception in your thought process is bolded:
new Derived first calls new Base, which calls addValue() and (as addValue() defined in Base adds up value by 10) value should be 10 at that time. then, Derived's addValue() is called which makes value 30 (because addValue() defined in Derived adds value up by 20).
Although addValue
is placed inside the base class constructor, it is still calling addValue
on this
, like this:
this.addValue();
Well, what is this
? It is a Derived
class instance. What does the derived class's addValue
do? It adds 20. That's why you got 40.
回答2:
Yes, it is a pretty good example of how polymorphism works.
The parent addValue
method is never called here, because of the overridden child method. It's called virtual method invocation. Consequently, if the child method is called twice, the result will be 40
.
回答3:
It is because Derived does an implicit call to super, but it will call the overrided addvalue in Derived. This is why you should not call overridable methods in your constructor.
You can find this out by creating a break point on the first line in your main() and let a debugger show you the steps.
回答4:
Java behaves differently from C++ in this respect. In C++, the object is considered only partially constructed while the parent constructor executes, so it will execute the parent's method. In Java it will always execute the most-derived implementation of the method.
来源:https://stackoverflow.com/questions/45264611/method-called-by-parent-constructor-behaves-as-child-method