Java 父构造函数调用的方法的行为与子方法相同

Java 父构造函数调用的方法的行为与子方法相同,java,class,polymorphism,hierarchy,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("Cal

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

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


由于被重写的子方法,这里永远不会调用父
addValue
方法。它叫。因此,如果两次调用child方法,结果将是
40

是的,这是多态性工作原理的一个很好的例子


由于被重写的子方法,这里永远不会调用父
addValue
方法。它叫。因此,如果两次调用child方法,结果将是
40

思维过程中的错误观念将被加粗:

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

虽然
addValue
被放置在基类构造函数中,但它仍然在
this
上调用
addValue
,如下所示:

this.addValue();

那么,这是什么?它是一个
派生的
类实例。派生类的
addValue
做什么?加20。这就是你得到40分的原因。

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

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

虽然
addValue
被放置在基类构造函数中,但它仍然在
this
上调用
addValue
,如下所示:

this.addValue();

那么,这是什么?它是一个
派生的
类实例。派生类的
addValue
做什么?加20。这就是为什么您得到了40。

这是因为派生函数隐式调用super,但它将在派生函数中调用重写的addvalue。这就是为什么不应该在构造函数中调用可重写的方法


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

这是因为派生函数隐式调用super,但它将调用派生函数中重写的addvalue。这就是为什么不应该在构造函数中调用可重写的方法


你可以在主()中的第一行上创建一个断点,并让调试器显示步骤。

在C++方面,java的行为与C++不同。C++中,父构造函数执行时,对象只被部分构造,因此它将执行父方法。在Java中,它总是执行该方法的最派生的实现。java/< P> < >在C++方面与java不同。C++中,父构造函数执行时,对象只被部分构造,因此它将执行父方法。在Java中,它将始终执行该方法最派生的实现。

请回答另一个问题。如果我将value变量更改为static,并且将addValue()都更改为static,它将打印30。那么发生了什么?@GeorgeTheGood这是因为静态方法不受多态性的影响<放置在基类构造函数中的code>addValue将调用
base.addValue
。请回答另一个问题。如果我将value变量更改为static,并且将addValue()都更改为static,它将打印30。那么发生了什么?@GeorgeTheGood这是因为静态方法不受多态性的影响<放置在基类构造函数中的code>addValue将调用
base.addValue
。请回答另一个问题。如果我将value变量更改为static,并且将addValue()都更改为static,它将打印30。发生了什么事?@GeorgeTheGood,它被称为。这里没有与实例的连接,因此将从定义该类方法的上下文调用该类方法,请回答另一个问题。如果我将value变量更改为static,并且将addValue()都更改为static,它将打印30。发生了什么事?@GeorgeTheGood,它被称为。这里没有与实例的连接,因此将从定义该类方法的上下文和另一个快捷方式调用该类方法。如果我将value变量更改为static,并且将addValue()都更改为static,它将打印30。发生了什么事?请再来一杯。如果我将value变量更改为static,并且将addValue()都更改为static,它将打印30。发生了什么事?请再来一杯。如果我将value变量更改为static,并且将addValue()都更改为static,它将打印30。那么发生了什么?它从
Base()
调用
Base.addValue()
,从
Derived()
调用
Derived.addValue()
,因为静态方法不会被重写。请再快速调用一次。如果我将value变量更改为static,并且将addValue()都更改为static,它将打印30。那么发生了什么?它从
Base()
调用
Base.addValue()
,从
Derived()
调用
Derived.addValue()
,因为静态方法不会被重写。