当我有A类和B类时,这些命令有什么区别,其中B扩展A,并且它们有一个公共实例变量 size ,下面的命令是从方法中调用的< B>
中强> printSize1class 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);
}
}
答案 0 :(得分:2)
我有一个A类和一个B类,其中B延伸A,它们有一个共同的实例变量 size
不,他们没有。他们有单独的实例变量名为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
1}}也是A
。由于引用的类型为A
,因此A
的{{1}}被使用。
在这个特定的情况下,两者之间没有太大的区别,但是如果你在层次结构中添加了另一个层,那就是:
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()
的{{1}} 。但B
是特殊的,因为printSize
是特殊的,绕过多态,让super.printSize()
访问super
的{{1}}。