[英]Java Inheritance strange behaviour
The following code prints output as 40 instead of 30. I'm not able to figure out the solution. 以下代码将输出打印为40而不是30.我无法找出解决方案。 Please help with the code.
请帮助代码。
class Base {
int value = 0;
Base() {
addValue();
}
void addValue() {
value += 10;
}
int getValue() {
return value;
}
}
class Derived extends Base {
Derived() {
addValue();
}
void addValue() {
value += 20;
}
}
public class Test{
public static void main(String[] args) {
Base b = new Derived();
System.out.println(b.getValue());
}
}
The implicit super reference in Derived
constructor calls Base
constructor which in turn calls method addValue()
in the class Base
results in value variable as 10 and then addValue()
in the Derived
class should add 20 to value 10. So the final output is 30. Derived
构造函数中的隐式超级引用调用Base
构造函数,它反过来调用类Base
中的方法addValue()
导致value变量为10,然后Derived
类中的addValue()
应该将20加到值10.因此最终输出为30 。
But the code prints 40. 但代码打印40。
The addValue
method is overridden in the Derived
class. 在
Derived
类中重写了addValue
方法。 When a method is overridden, calling a method on an instance of this class always calls the overridden version, even when the call happens in the base class. 重写方法时,即使在基类中调用时,调用此类实例上的方法也始终调用重写版本。
在Derived
类中,方法void addValue()
指向Derived中定义的方法,而不是Base
定义的方法
Most probably when you extend the Base class 最有可能在扩展Base类时
class Derived extends Base {
Derived() {
addValue();
}
void addValue() { //here
value += 20;
}
}
you put the method name same in the Base Class
and this overrides the default one which is: 您将方法名称设置为
Base Class
相同,这将覆盖默认值:
void addValue() {
value += 10;
}
So, the output is 40 -> 20 + 20 因此,输出为40 - > 20 + 20
As others have got there before me: addValue
is overridden in Derived
, as it is an accessible method with the same name and same parameter types. 正如其他人在我之前
addValue
: addValue
在Derived
被覆盖,因为它是一个具有相同名称和相同参数类型的可访问方法。 Typically you would add the @Override
annotation to the override method. 通常,您会将
@Override
注释添加到覆盖方法。 The method in the derived class even though the base class is still under construction. 即使基类仍在构建中,派生类中的方法。
Not all languages do the same thing. 并非所有语言都做同样的事情。 C++, for example, will not run overridden methods from derived class whilst the base constructor is still running.
例如,C ++不会在派生类中运行重写方法,而基本构造函数仍在运行。 The equivalent program in C++ does show 30.
C ++中的等效程序确实显示30。
#include <iostream>
class Base {
public:
int value;
Base() : value(0) {
addValue();
}
virtual void addValue() {
value += 10;
}
int getValue() {
return value;
}
};
class Derived : public Base {
public:
Derived() {
addValue();
}
virtual void addValue() {
value += 20;
}
};
int main() {
Base *b = new Derived();
std::cout << b->getValue() << std::endl;
}
addValue()
is override in Derived
class and you created a Derived
class object. addValue()
在Derived
类中被覆盖,您创建了一个Derived
类对象。 So whenever the addValue()
called by this instance. 所以每当
addValue()
被这个实例调用时。 Always methos is called of Derived
class. 始终将方法称为
Derived
类。 So thats why addValue()
of Derived class called twice. 这就是为什么Derived类的
addValue()
调用两次。 Once in the Base
class constructor and second in Derived
class constructor. 一次在
Base
类构造函数中,第二个在Derived
类构造函数中。
As others discussed earlier Method Overriding property applies to method call in the base class well. 正如前面讨论的其他方法一样,Method Overriding属性适用于基类中的方法调用。
By this java applies Run Time Polymorphism ie, Based on the object that is invoked at run time, the method which is to be executed is decided. 通过这个java应用运行时多态性, 即,基于在运行时调用的对象,确定要执行的方法。 For eg,
例如,
If we don't want to override, we can make the parent method as private
instead of default private package . 如果我们不想覆盖,我们可以将父方法设为
private
而不是默认私有包 。 Now we will be getting 30 as output. 现在我们将获得30作为输出。 As the method which cannot be inherited then it cannot be overridden
作为无法继承的方法,它不能被覆盖
class Base {
int value = 0;
Base() {
addValue();
}
private void addValue() {
value += 10;
}
int getValue() {
return value;
}
}
class Derived extends Base {
Derived() {
addValue();
}
void addValue() {
value += 20;
}
}
public class Test{
public static void main(String[] args) {
Base b = new Derived();
System.out.println(b.getValue());
}
}
Now, the output is 30 . 现在,输出是30 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.