Java 继承字段

2022-09-01 16:34:04

我无法理解以下输出。

我不知道为什么输出是10,我认为该行创建了B类的新实例,我认为结果应该是20A a = new B()

class A {
    int i = 10;
}

class B extends A {
    int i = 20;
}

public class MainClass {
    public static void main(String[] args) {
        A a = new B();

        System.out.println(a.i);
    }
}

为什么这是这样工作的..请解释。


答案 1

首先,请参阅隐藏字段(着重号是后加的)

在类中,与超类中的字段同名的字段将隐藏超类的字段,即使其类型不同

换句话说,这不是“继承”,因为你实际上隐藏在 后面,并且你正在使用的引用对象,所以你得到了它的字段。如果这样做,您将看到 ,如预期的那样。AiBiAB b = new B()20


如果期望真正的重写,请尝试使用方法。

class A {
    public int get() { 
        return 10; 
    }
}

class B extends A {
    @Override 
    public int get() { 
        return 20; 
    }
}

A a = new B();
System.out.print(a.get()); // 20

如果您真的想同时查看两者,请参阅此示例。

class A {
    int i = 10;
}

class B extends A {
    int i = 20;

    @Override 
    public String toString() { 
        return String.format("super: %d; this: %d", super.i, this.i);
    }
}

A a = new B();
System.out.print(a); // super: 10; this: 20

答案 2

在 java 中,您无法覆盖实例变量。您获得的输出是预期的。在 Java 中,您只能重写实例方法,而不能重写实例变量。

如果希望 20 作为输出,则可以对这些实例变量使用 getter 方法。

 class A {
    int i = 10;

    int getI() {
        return i;
    }
}

class B extends A {
    int i = 20;

    int getI() {
        return i;
    }
}

public class MainClass {
    public static void main(String[] args) {
        A a = new B();

        System.out.println(a.getI());
    }
}

推荐