我有一个问题,为什么这段代码在执行时打印出值0.我不完全理解SubClass构造函数中发生了什么,为什么当我擦除被覆盖时方法implicitValue,它打印出10. SubClass构造函数是否使用SuperClass构造函数? 谢谢。
class SuperClass {
protected int superClassValue;
public SuperClass() {
superClassValue = implicitValue();
}
public int implicitValue() {
return 10;
}
public int getValue() {
return superClassValue;
}
}
class SubClass extends SuperClass {
private int subClassValue;
public SubClass() {
subClassValue = 20;
}
public int implicitValue() {
return subClassValue;
}
}
class Example {
public static void main(String argv[]) {
SubClass ss = new SubClass();
System.out.println("The value is " + ss.getValue());
}
}
答案 0 :(得分:3)
TL; DR
问题是来自implicitValue
的{{1}}由超类隐式SuperClass构造函数(SubClass
)通过super()
方法使用,之后implicitValue()
将在SubClass中执行构造函数,因此它返回subClassValue = 20;
的默认值,subClassValue
字段为int
。
SubClass构造函数是否使用SuperClass构造函数?
是的,start的子类构造函数总是调用超类构造函数,所以代码
0
与
相同public SubClass() {
subClassValue = 20;
}
但是让我们来看看你的代码。您正在打印超类中存在的public SubClass() {
super();//superclass constructor
subClassValue = 20;
}
方法的结果
getVlaue()
如您所见,它会返回public int getValue() {
return superClassValue;
}
的值。在调用superClassValue
之前,您正在创建getVlaue()
实例,因此您正在调用代码
ss
表示你正在调用超类的构造函数,它看起来像
super();//superclass constructor
subClassValue = 20;
所以使用public SuperClass() {
superClassValue = implicitValue();
}
方法的返回值初始化this.superClassValue
,但由于dynamic binding(后期绑定),JVM将尝试从实际类{{}开始搜索此方法的实现{1}} implicitValue()
,由于此类有自己的重写版本,因此将调用它
this
但SubClass
尚未设置为
public int implicitValue() {
return subClassValue;
}
因此subClassValue
仍有默认值super();// <-- we are still here
subClassValue = 20;// this line was not executed yet
,这意味着
subClassValue
所以
0
将返回superClassValue = implicitValue(); //will be initialized with 0;
。
答案 1 :(得分:1)
是的,如果没有明确给出这样的调用,子类构造函数会隐式调用超类构造函数。但由于在0
中覆盖了implicitValue
方法,因此会打印SubClass
。
SuperClass
部分。所有变量都已初始化。由于没有给出明确的值,编译器会为superClassValue
提供默认值0
。然后超类构造函数调用implicitValue()
,它调用子类的方法。此方法返回superClassValue
,其初始化为0
。此值已明确分配回superClassValue
。subClassValue
初始化为10
。getValue()
方法,它返回superClassValue
,即0
。 The value is 0
已打印。如果您要删除implicitValue
中的SubClass
方法,则会继承该方法的SuperClass
版本,该方法会返回10
。< / p>
如果您要修改implicitValue
中的SubClass
方法以返回5
,那么它会将superClassValue
初始化为5
,并会打印{ {1}}。
答案 2 :(得分:1)
在您的情况下:默认情况下将调用SuperClass构造函数。
当Java进程:新的SubClass()时。它将首先调用SuperClass的构造函数。当调用SuperClass的构造函数时 - 从implicitValue()返回的值将被赋值给superClassValue - 被调用的方法implicitValue()是SubClass的方法(按照你的想法调用SupperClass的NOT implicitValue() - OOP的多态性特征) 。当调用SubClass的implicitValue()时,subClassValue尚未初始化(subClassValue = 20;尚未运行),因此subClassValue仍为ZERO。这就是你在输出中看到零的原因。
在SubClass中删除override implicitValue时。 hiddenValue()被调用是SupperClass的implicitValue - &gt;这就是你在输出中看到10的原因。
答案 3 :(得分:-1)
听起来你的Override方法或子类有问题。因为它听起来就像它实现了一个变量,值没有被实例化,所以它默认为0然后当你删除它时超类接管导致你获得值10。