为什么这里输出是5而不是15? 根据代码将x的值修改为15:
class A {
int x = 5;
public int getX() {
return this.x;
}
public void setX(int x) {
this.x = x;
}
}
class B extends A {
int x = 10;
public B() {
this.x = 15;
}
}
public class Test {
public static void main(String[] args) {
B a = new B();
System.out.println("hello" + a.getX());
}
}
是因为变量作用域的原因吗?
您在
x
中再次重新声明了 B
:
class B extends A {
int x = 10; // <--- here
这将创建两个名为
x
的字段。从现在开始我将把它们称为A.x
和B.x
。请注意,B.x
隐藏了 A.x
。这意味着如果变量的编译时类型是A
,则只能访问A.x
,而如果编译时类型是B
,则只能访问B.x
。
当您执行
new B()
时,A.x
会初始化为 5
。 B.x
在构造函数中设置为 15
。到目前为止很简单。
但是后来你打来了
getX()
。请注意,这是来自 A
的方法。它不知道B.x
的存在,因为在它内部,this
的编译时类型是A
。所以在getX
里面,this.x
意味着A.x
。这就是返回 5
的原因。
要输出
15
,您可以直接访问B.x
:
System.out.println(a.x);
或者,
B
可以覆盖A.getX
和A.setX
以返回并设置B.x
:
class B extends A {
int x = 10;
public B() {
this.x = 15;
}
@Override
public int getX() {
return x;
}
@Override
public void setX(int x) {
this.x = x;
}
}
a.getX() 调用超类的 get 方法,从而返回 A 类中 x 的值。
当你在 B 类中添加 getter 时,你得到的 x 值为 15。
class A {
int x = 5;
public int getX() {
return this.x;
}
public void setX(int x) {
this.x = x;
}
}
class B extends A {
int x = 10;
public B() {
this.x = 15;
}
public int getX() {
return this.x;
}
}
public class Test {
public static void main(String[] args) {
B a = new B();
System.out.println("hello" + a.getX());
}
}
您无法重新初始化超类中存在的子类中的变量。这样,当获取 x 时,它将返回超类的 x 值而不是子类的值。所以在 B 类中,不要使用
int x = 10
,而是使用 x = 10
类 B 中没有定义 getX(),因此它将引用超类来获取该方法的引用,因为在超类中找到了引用,所以它将执行超类的 getX() 方法。
如果你在B类中添加getX(),那么同样会被执行。
class A {
int x = 5;
public int getX() {
return this.x;
}
public void setX(int x) {
this.x = x;
}
}
class B extends A {
int x = 10;
public B() {
this.x = 15;
}
public int getX() {
return this.x;
}
}
public class Test {
public static void main(String[] args) {
B a = new B();
System.out.println("hello" + a.getX());
}
}
结果为 15。