以下命令中 super 和 this 的区别?
Difference between super and this in the commands below?
当我有一个 class A 和一个 Class B 时,这些命令之间有什么区别,其中 B 扩展了 A ,并且它们有一个共同的实例变量 size 下面的命令是从 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);
}
}
我也和这两个有同样的问题。我有一个 class A 和一个 class B,其中 B 扩展了 A,它们都有一个同名的方法 printSize 和一个实例变量 size 和下面的命令是从 printSize2 inside class B.
方法调用的
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);
}
}
i have a class A and a Class B where B extends A which they have a common instance variable size
不,他们没有。他们有 单独的 个名为 size
的实例变量。一个在与A关联的对象部分,另一个在与B关联的对象部分。我们称它们为A$size
和B$size
。为了让他们有一个 common 实例变量,你需要从 B
中删除 size
的声明,所以他们都使用 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
(通过 cast),而 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)this).printSize()
中的 A
类型并不重要,您仍然会得到 B
的 printSize
.但是 super.printSize()
是特殊的,因为 super
是特殊的并且绕过了多态性,让 B
可以访问 A
的 printSize
.
当我有一个 class A 和一个 Class B 时,这些命令之间有什么区别,其中 B 扩展了 A ,并且它们有一个共同的实例变量 size 下面的命令是从 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);
}
}
我也和这两个有同样的问题。我有一个 class A 和一个 class B,其中 B 扩展了 A,它们都有一个同名的方法 printSize 和一个实例变量 size 和下面的命令是从 printSize2 inside class B.
方法调用的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);
}
}
i have a class A and a Class B where B extends A which they have a common instance variable size
不,他们没有。他们有 单独的 个名为 size
的实例变量。一个在与A关联的对象部分,另一个在与B关联的对象部分。我们称它们为A$size
和B$size
。为了让他们有一个 common 实例变量,你需要从 B
中删除 size
的声明,所以他们都使用 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
(通过 cast),而 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)this).printSize()
中的 A
类型并不重要,您仍然会得到 B
的 printSize
.但是 super.printSize()
是特殊的,因为 super
是特殊的并且绕过了多态性,让 B
可以访问 A
的 printSize
.