Java 字段继承和向上转换的奇怪行为

Java field inheritance and upcasting weird behaviour

这个问题的灵感来自我偶然发现的

给定以下代码:

public class Test {

    public static void main(String[] args) {
        Derived b = new Derived();
        Base a = b;

        System.out.println("b.i -> " + b.i);
        System.out.println("a.i -> " + a.i);
        System.out.println("b.getI() -> " + b.getI());
        System.out.println("a.getI() -> " + a.getI());
    }
}

class Base {
    int i = 1;

    public int getI() {
        return i;
    }
}

class Derived extends Base {
    int i = 2;

    public int getI() {
        return -i;
    }
}

// Output:
// b.i -> 2
// a.i -> 1
// b.getI() -> -2
// a.getI() -> -2

有人可以解释为什么 a.i 返回 1 吗?它不应该访问 Derived class 中的 i 字段吗?

另外,在调试代码的时候,我可以看到这样的东西:

在那里你可以看到 Derived class 正在存储对 Base.i 的引用。

为什么会这样? Base.i不应该被Derived.i继承和覆盖吗?

根据 ,Java 中没有字段多态性。这意味着子类中的字段只是隐藏超类中的字段,而不是重载它。

经过更深入的谷歌搜索,我最终找到了这个问题的答案 here

重点是成员变量不能像方法一样被覆盖,它们只是隐藏的,向上转型允许访问基类中的隐藏方法class。

您遇到了 Java 的功能,称为变量隐藏。 Derived中的字段"i"隐藏了class中的字段"i"Base.

与方法不同,java 中的字段不能被覆盖,因此是行为。

我找到了关于这个主题的非常深入的 tutorial,您可能认为有用