我正在java中测试一些多态性,我的代码如下所示:
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());
}
}
所以这里的东西是,它打印40但是我猜它应该打印30.我的想法是:new Derived首先调用new Base,调用addValue()
和({{1} }在Base中定义的值加10)当时值应为10。然后,调用Derived' addValue()
使得值30(因为在Derived中定义的addValue()
将值增加20)。但相反,Base会调用它的孩子addValue()
。有人能解释一下发生了什么吗?
答案 0 :(得分:4)
你思想过程中的误解是粗体:
new Derived第一次调用new Base,调用addValue()和(因为Base中定义的addValue()将值加10)当时值应为10。然后,Derived的addValue(调用使得值为30(因为在Derived中定义的addValue()将值增加20)。
虽然addValue
放在基类构造函数中,但它仍在addValue
上调用this
,如下所示:
this.addValue();
嗯,this
是什么?它是一个Derived
类实例。派生类的addValue
做了什么?它增加了20.这就是为什么你有40岁。
答案 1 :(得分:1)
是的,这是多态性如何运作的一个很好的例子。
由于重写的子方法,从不在此调用父addValue
方法。它被称为virtual method invocation。因此,如果调用子方法两次,结果将为40
。
答案 2 :(得分:1)
这是因为Derived对super进行了隐式调用,但它会在Derived中调用覆盖的addvalue。这就是为什么你不应该在构造函数中调用可覆盖的方法。
您可以通过在main()的第一行创建断点来找到它,然后让调试器显示步骤。
答案 3 :(得分:1)
Java在这方面与C ++的行为不同。在C ++中,只有在父构造函数执行时才会认为对象是部分构造的,因此它将执行父方法。在Java中,它总是执行该方法的派生程度最高的实现。