java - 实例字段的继承如何在此特定代码中工作?

标签 java inheritance

class A
{
    int a = 2, b = 3;
    public void display()
    {
        int c = a + b;
        System.out.println(c);
    }
}
class B extends A
{
    int a = 5, b = 6;
}
class Tester
{
    public static void main(String arr[])
    {
        A x = new A();
        B y = new B();
        x.display();
        y.display();
    }
}

为什么输出为 5,5?而不是 5,11?。y.display() 方法如何工作?

最佳答案

why does the output comes 5,5?

因为 A.display() 只知道 A.aA.b 字段。这些是 A 中的任何代码都知道的唯一字段。看起来您希望 B 中的声明“覆盖”现有的字段声明。他们没有。他们声明了 字段,这些字段隐藏 现有字段。变量的行为实际上与方法的行为方式不同——覆盖变量的概念根本不存在。来自 the JLS section 8.3 :

If the class declares a field with a certain name, then the declaration of that field is said to hide any and all accessible declarations of fields with the same name in superclasses, and superinterfaces of the class.

您可以通过更改 B 来获得所需的效果,以便其构造函数更改它从 A 继承的现有字段的值:

class B extends A {
    B() {
        a = 5;
        b = 6;
    }
}

请注意,这些是不是变量声明。他们只是任务。当然,在大多数代码(好吧,我见过的大多数代码)中,A 中的字段都是私有(private)的,因此无法从 B 访问,但这是只是为了解释语言行为的例子。

关于java - 实例字段的继承如何在此特定代码中工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21377859/

相关文章:

C++继承加运算符

python - 为什么在这种情况下从 namedtuple 继承会导致无限递归?

java - 如何避免 Android 中的 OutOfMemoryError

java - 公共(public)接口(interface) ITMark<E extends Comparable<E>>

java - Google 云存储 java - 如何在以编程方式上传时授予对文件的访问权限

c++ - 有没有办法用父类的命名空间/类空间来引用子类?

接受类及其接口(interface)的 Java 类型(逆变)

java - 设计模式 : Lazy Singleton, 泛型和继承 : java. lang.Class 无法转换为 java.lang.reflect.ParameterizedType

java - 如何在 jetty 服务器中为 CSS、Javascript、图像等静态资源设置过期 header

java - 如何在...中播放一次音乐?