当我拥有A类和B扩展了A的B类并且它们具有公共实例变量大小并且下面的命令从B内部的printSize1方法调用时,这些命令之间有什么区别?
class A {
protected int size;
}
class B extends A {
protected int size=7;
public void printSize1() {
System.out.println(((A)this).size)
System.out.println(super.size);
}
}
我对这两个也有同样的问题。我有一个类A和一个类B,其中B扩展了A,并且它们都具有一个具有相同名称printSize和一个实例变量size的方法,并且下面的命令是从类B内部的方法printSize2调用的。
class A {
protected int size;
public void printSize() {
System.out.println("Size=" + size);
}
}
class B extends A {
protected int size=7;
public void printSize2 {
((A) this).printSize();
super.printSize();
}
public void printSize() {
System.out.println ("MSize="+size);
}
}
最佳答案
我有一个A类和一个B类,其中B扩展了A,它们具有相同的实例变量大小
不,他们没有。它们具有称为size
的单独的实例变量。一个在与A关联的对象部分中,另一个在与B关联的对象部分中。让我们将它们称为A$size
和B$size
。为了使它们具有公共实例变量,请从size
中删除B
的声明,以便它们都使用A$size
。
重新声明祖先的非private
实例变量(字段)总是一个坏主意,因为这会导致这种混乱。
下面的两个示例代码输出0
,因为它们都在访问A$size
,而您从未为其分配值,因此默认值为0
:
System.out.println(((A)this).size); // 0
System.out.println(super.size); // 0
所以问题是:为什么他们都使用
A$size
而不是B$size
?由于引用的类型,我们用来查找size
。在这两种情况下,引用的类型均为A
,因为(A)this
的类型为A
(通过强制转换),并且super
中的方法中的B
的类型也为A
。由于引用的类型为A
,因此将使用A
的size
。在这种特殊情况下,两者之间没有太大的区别,但是如果您向层次结构中添加了另一层,那就会有很大的区别:
class A {
protected int size = 1;
}
class B extends A {
protected int size = 2;
}
class C extends B {
protected int size = 3;
void printSize() {
System.out.println(((A)this).size); // 1
System.out.println(super.size); // 2
System.out.println(this.size); // 3
}
}
故事的寓意:不要重新声明由祖先声明的实例变量(除非祖先的版本为
private
)。请注意,变量与方法不同。实例方法是多态的。实例变量不是。使用方法,您可以获得与对象的最终类型关联的方法(除非您使用
super
或合格的super
,因为它们是特殊的并且绕过了多态性)。这就是您在
printSize2
的第二个示例中所要发挥的作用。因为方法是多态的,所以不必将this
强制转换为A
中的((A)this).printSize()
类型,仍然会得到B
的printSize
。但是super.printSize()
是特殊的,因为super
是特殊的,并且绕过了多态性,使B
可以访问A
的printSize
。关于java - 在下面的命令中,super和this之间的区别?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42876391/