Java继承字段

dhS*_*dhS 26 java inheritance

我无法理解以下输出.

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

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么这样工作..请解释.

cri*_*007 32

首先,看隐藏字段(重点添加)

在类中,与超类中的字段具有相同名称的字段会隐藏超类的字段,即使它们的类型不同

换句话说,这是不是"遗产",因为你实际上隐藏Ai背后Bi,和你正在使用的参考对象A,所以你得到它的领域.如果你这样做B b = new B(),你会看到20,如预期的那样.


如果您期望真正的覆盖,请尝试使用方法.

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

class B extends A {
    @Override 
    public int get() { 
        return 20; 
    }
}
Run Code Online (Sandbox Code Playgroud)

看到

A a = new B();
System.out.print(a.get()); // 20
Run Code Online (Sandbox Code Playgroud)

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

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

A a = new B();
System.out.print(a); // super: 10; this: 20
Run Code Online (Sandbox Code Playgroud)


Ami*_*kar 18

在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());
    }
}
Run Code Online (Sandbox Code Playgroud)


pun*_*303 12

多态性不适用于Java 中的字段.评估变量决策是在编译时进行的,因此始终要访问基类变量.