Java继承混乱,超类和子类成员变量同名
在运行此代码时
class c1 { int ci = 1; }
class c2 extends c1 { int ci = 2; }
class inheritanceTest {
public static void main(String args[]) {
c1 c1reftoc2 = new c2();
System.out.println(c1reftoc2.ci);
}
}
输出为1
。所以我猜一个带有超类引用变量的子类对象,在两个类中的变量名称相同的情况下使用超类变量
但是,从一个SCJP问题运行这个程序
class Foo {
public int a = 3;
public void addFive() {
a += 5;
System.out.print("f ");
}
}
class Bar extends Foo {
public int a = 8;
public void addFive() {
System.out.println(this.a);
this.a += 5;
System.out.print("b " );
System.out.println(this.a);
}
}
class SCJPQC3 {
public static void main(String[] args) {
Foo f = new Bar();
f.addFive();
System.out.println(f.a);
}
}
输出为
8
b 13
3
由于重写,在main()
中调用的addFive()
方法将是类Bar
的方法
在{main()
中的f.a
给出了3
。由this.
和f.
引用的实例是相同的,但它们给出不同的结果。使用this.a
将8
作为输出,这与我之前的理解相矛盾
所以我的问题是,this.
指的是类还是实例?我知道this.
会引用调用方法的对象,但这个特定的程序让我感到困惑
# 1 楼答案
当在子类中用与超类中相同的名称声明变量时,与被覆盖的方法不同,您是在隐藏变量。这个区别是因为f指向一个Bar类型的对象,所以使用了Bar中的addFive()方法。然而,当调用f.a时,它的引用类型是Foo,它首先在那里寻找变量。因此,通常应避免在子类中隐藏变量
# 2 楼答案
这里的关键字}{}的
this
指的是调用方法的当前对象实例。由于多态性,调用了Bar
的addFive
方法。该方法引用了那里作用域中的a
,即Bar
的a
。(Bar
的a
隐藏了Foo
的a
。)这就是8
最初打印的原因,也是它更改为13
的原因。然而,当在main
的末尾调用System.out.println(f.a);
时,编译器只将f
视为Foo
变量,因此它打印3
{3
变量,它从未从3
更改