Java继承字段

Java继承字段,java,inheritance,Java,Inheritance,我无法理解以下输出 我不知道为什么输出是10,我认为行aaa=newb()创建了一个类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

我无法理解以下输出

我不知道为什么输出是10,我认为行
aaa=newb()
创建了一个类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);
    }
}

为什么会这样。。请解释。

成员变量
i
已在
A类中定义

为了实现您想要的目标,请更改
B类
,如下所示:

class B extends A {
    public B() {
      i = 20;
    }
}

在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());
    }
}
首先,请参见(添加了重点)

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

换句话说,这不是“继承”,因为您实际上将
A
i
隐藏在
B
i
后面,并且您使用的是
A
的引用对象,因此您得到了它的字段。如果您执行了
B=new B()
,您将看到预期的
20


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

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

class B extends A {
    @Override 
    public int get() { 
        return 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);
    }
}


多态性不适用于Java中的字段。计算变量的决策是在编译时做出的,因此始终访问基类变量。

因为您定义了两个变量:一个在子类
B
中,另一个在超类
A
中具有相同名称

A a = new B();
a.i; // refers to A.i
如果将
A
转换为
B
,它将访问
B.i

System.out.println(((B)a).i);
我认为您需要使用1个变量:

class A {
    int i;

    public A() {
        i = 10;
    }
}

class B extends A {
    public B() {
        i = 20;
    }
}

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

        System.out.println(a.i); // will print 20
}

你没有在这里覆盖
i
的值,你在跟踪查看这篇文章。多态性不适用于字段,而适用于方法。您使用了类型为
a
的变量来查找字段
i
,因此您在类型
a
中获得了
i
的副本,而不是类型
B
中的副本。查找字段时,重要的是变量的类型,而不是对象的类。
System.out.println(((B)a).i);
class A {
    int i;

    public A() {
        i = 10;
    }
}

class B extends A {
    public B() {
        i = 20;
    }
}

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

        System.out.println(a.i); // will print 20
}