提问人:Alden Luthfi 提问时间:6/4/2023 更新时间:6/4/2023 访问量:53
此 Java 行为背后的推理 [重复]
Reasoning Behind this Java Behaviour [duplicate]
问:
上下文
假设我们有一个这样的类继承结构
class A {
int z = 10;
public void display() {
System.out.println("A's z is " + z);
}
}
class B extends A {
int z = 20;
public void display() {
System.out.println("B's z is " + z);
}
public void onlyB() {
System.out.println("This is only in B");
}
}
class Main {
public static void main(String args[]) {
A obj = new B();
System.out.println(obj.z); // 10
obj.display(); // B's z is 20
}
}
问题
为什么给出 's 但使用 's,有没有办法考虑这个问题,使其在逻辑上有意义?obj.z
A
z
obj.display()
B
z
试图暗化
通过说
A obj = new B();
在我看来,这是在说“创建一个 A 类型的对象,但使用 B 的所有实现”
根据这个推理,对象不能使用是合乎逻辑的,因为它是 类型,并且没有 。同样通过这个推理,将使用 的实现。但是为什么调用使用 's 而不是 's?对象不应该使用 的实现吗?onlyB()
A
A
onlyB()
display()
B
z
A
z
B
B
z
我知道这在实践中不会出现,但我很好奇。如果能更好地解释为什么会发生这种情况,将不胜感激。
答:
您已经引入了可变阴影。该字段不同于 (并继承,但隐藏了 )。但是,如果您将其从B.z
A.z
A.z
class B extends A {
int z = 20;
到类似的东西
class B extends A {
public B() {
this.z = 20;
}
那么它实际上是继承,只会有一个.z
在 Java(以及我所知道的大多数语言)中,字段不会被覆盖。因此,如果您在父类中定义一个字段,并在子类中定义一个同名的其他字段,则这两个字段都将存在在那里(并且每个字段都可以在其类中正常访问)。(考虑将 your in 定义为 String not int!,现在它们有不同的类型,并且看到一个 String )。z
B
B
z
但是非静态方法可以被覆盖。
当你有一个实例时,你有一个 的实例,但引用类型为 A。当访问字段(不可覆盖)时,则 你正在访问 ,但是当你调用方法(被覆盖)时,通过 a 和 B 的方法调用查找的真正方法被调用(这就是继承的力量),并且该方法访问它自己的方法。(再次考虑在 B 中为 ,则 int 类型不是 String 类型,后者位于 的类型类中)。A obj = new B()
B
A.z
dynamic lookup table
z
z
String
obj.z
obj
评论