父构造函数调用的方法表现为子方法

时间:2017-07-23 11:35:52

标签: java class polymorphism hierarchy

我正在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()。有人能解释一下发生了什么吗?

4 个答案:

答案 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中,它总是执行该方法的派生程度最高的实现。