【问题标题】:How fields work in Polymorphism Java? [duplicate]多态 Java 中的字段如何工作? [复制]
【发布时间】:2016-10-05 01:52:25
【问题描述】:

我正在阅读 Interview Questions 关于 java 的内容,并找到了很好的示例并感到困惑。因为没有很好/更多的解释可以帮助我理解这个例子。这是一个例子。

public class MainClass {
    public static void main(String[] args) {
      Parent p = new Child();
      System.out.println(p.getObject().x);
    }
}

class Parent {
    int x = 10;

    public Parent getObject() {
        System.out.println("Parent Object");
        return new Child();
    }
} 

class Child extends Parent {
    int x = 20;

    public Child getObject() {
        System.out.println("Child Object");
        return new Child();
    }
}

输出:

Child Object
10

但是当我将 Parent 类的 getObject 的返回类型更改为 Child 时。

public Child getObject() {
        System.out.println("Parent Object");
        return new Child();
    }

然后我得到输出

Child Object
20

我知道字段不包含在多态中。

我很困惑,在更改 Parent 的 getObject() 的返回类型之后和之前的示例中结果应该相同;方法。

【问题讨论】:

    标签: java polymorphism


    【解决方案1】:

    您的Child 类有两个x 成员——一个是它直接声明的,另一个是从Parent 继承的。当您使用Child 引用时,Childx 成员隐藏了从Parent 继承的成员。当您使用Parent 引用时,您会看到Parentx 成员。

    因此,当您将getObject() 的返回类型从Parent 更改为Child 时,p.getObject().x 会返回不同x 成员的值。

    【讨论】:

    • 因为返回类型是 Child 的 getObject() 方法是 Child 那么它如何调用 parent 的 x 字段呢?
    • 字段绑定在编译时解析,因此编译器知道是读取Parent.x还是Child.x
    • @LetDoit 静态(编译时)返回类型为Parent(在您进行更改之前)。动态(运行时)类型是Child。编译时类型决定了哪些成员可以被访问。
    • 为什么 Java 会让一个参数影响另一个参数。至少在编译时应该有一个警告。 Jon Skeet 在这里stackoverflow.com/a/772694/5636313 有一个解释。但是,对我来说,他列出的原因应该不是什么大问题。
    【解决方案2】:

    经验法则是 - 类成员不会像方法那样被覆盖。返回的值取决于访问它所使用的引用。如果您使用父引用访问,则将返回父属性,如果引用属于子类,则将返回子属性。

    【讨论】:

    • 不清楚。返回的值取决于引用的正式类型。不是它的实际类型。
    猜你喜欢
    • 1970-01-01
    • 2011-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-20
    • 2012-02-25
    • 2017-06-01
    • 2015-02-04
    相关资源
    最近更新 更多