继承和类成员

时间:2010-02-10 16:03:44

标签: java polymorphism

下式给出:

class A
{
    String s = "A";
}

class B extends A
{
    String s = "B";
}

public class C
{
    public static void main(String[] args){ new C().go();}
    void go()
    {
        A a = new B();
        System.out.println(a.s);
    }
}

问题:

运行此代码时JVM背后的机制是什么?为什么a.s打印回“A”。

4 个答案:

答案 0 :(得分:4)

字段引用不受多态性的影响,因此在编译时编译器引用A的字段,因为您的局部变量是A类型。

换句话说,字段行为就像方法上的Java重载行为,而不是Java重写行为。

答案 1 :(得分:2)

您可能希望像方法一样覆盖字段,并根据对象的运行时类型进行动态分派。

这不是Java的工作方式。字段不会被覆盖,它们是隐藏的。这意味着B类的对象有两个字段,名为“s”,但访问哪些字段取决于上下文。

至于为什么会这样:覆盖字段是没有意义的,因为当类型不同时没有任何有用的方法可以使它工作,而当类型相同时就没有意义了(就像你一样)可以只使用超类字段)。就个人而言,我认为它应该只是一个编译器错误。

答案 2 :(得分:1)

这不是多态(如标记)。

Java有virtual methods,而不是虚拟成员变量 - 即你没有覆盖属性 - 你隐藏它。

答案 3 :(得分:0)

虽然成员变量是从基类继承的,但它们不是多态调用的(即动态调用不适用于成员变量)。

因此,a.s将引用基类中的成员而不是派生类。

话虽如此,代码并未遵循OO原则。类的成员需要是私有/受保护的(不是公共的或默认的),具体取决于业务用例,您需要提供公共方法来获取和设置成员的值。

相关问题