提问者:小点点

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


我正在测试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 Derive首先调用new Base,它调用addValue()并且(正如在Base中定义的addValue()将值相加10)当时的值应该是10。然后,Derive的addValue()被调用,这使得值为30(因为addValue()定义在Derive中将值相加20)。但是,Base调用了它的子addValue()。有人能解释一下发生了什么吗?


共3个答案

匿名用户

你思维过程中的误解是大胆的:

new Derived首先调用new Base,后者调用addValue()和(因为addValue()在Base中定义的值加起来是10)当时值应该是10。然后,调用Derived的addValue(),使值为30(因为在Derived中定义的addValue()将值增加20)。

尽管 addValue 放置在基类构造函数中,但它仍然在此调用 addValue,如下所示:

this.addValue();

嗯,是什么?它是一个派生类实例。派生类的 addValue 有什么作用?它增加了 20。这就是为什么你得到40。

匿名用户

是的,这是多态性如何工作的一个很好的例子。

此处永远不会调用父 addValue 方法,因为重写了子方法。这称为虚拟方法调用。因此,如果调用子方法两次,则结果将为 40

匿名用户

这是因为 Derived 对 super 进行了隐式调用,但它将调用 Derived 中被覆盖的 addvalue。这就是为什么你不应该在构造函数中调用可重写的方法。

您可以通过在main()中的第一行创建一个断点并让调试器向您展示步骤来找出这一点。