【问题标题】:Why the overridden method not exhibting polymorphic behaviour? [duplicate]为什么被覆盖的方法没有表现出多态行为? [复制]
【发布时间】:2017-11-19 15:32:44
【问题描述】:

我知道Variables doesn't exhibit polymorphic behavior,它仅限于方法。但是下面的代码在返回对象类型时有点混乱。

它调用了子方法(这是正确的),这意味着它正在返回子对象。那么为什么不打印子变量的值呢?

class Parent {

    int var = 11;

    public Parent getInstance() {
        System.out.println("In Parent ...");
        return new Parent();
    }
}

class Child extends Parent {

    int var = 22;

    public Child getInstance() {
        System.out.println("In Child ...");
        return new Child();
    }
}


public class VariableHiding {

    public static void main(String[] args) {
        Parent p = new Child();
        System.out.println(p.getInstance().var);  // something's fishy?
    }
}


// Output : In Child ...  11

PS : 它不是 this one 的副本(它谈到变量不参与多态性,但这里提到的那个返回子 obj 的对象,并且 obj 持有父类的 var 而不是它自己的)

【问题讨论】:

    标签: java inheritance polymorphism


    【解决方案1】:

    运行时多态性无法为变量实现。所以class Parent and Child 都有一个公共变量var

    Parent p = new Child();
    

    在这个p中,被class Child引用(它是Parent类的类型)。所以它总是引用超类变量。

    【讨论】:

      【解决方案2】:

      p.getInstance() 的返回类型是Parent,因为p 的编译时类型是Parent,而ParentgetInstance() 方法返回一个Parent

      如果你尝试写,你可以看到:

      Parent p = new Child();
      Child c = p.getInstance();
      

      不会通过编译。

      因此p.getInstance().var返回Parent类的实例变量。

      为了获得Child 类的实例变量,您必须将p.getInstance() 转换为Child

      System.out.println(((Child)p.getInstance()).var);
      

      或将p的类型改为Child

      Child p = new Child();
      System.out.println(p.getInstance().var);
      

      【讨论】:

      • 但是 p.getInstance() 的计算结果是 CHILD 对象,对吧?
      • @Snehal 运行时类型是 Child,而不是编译时类型。
      【解决方案3】:

      输出是 11 而不是 22 因为有行

       Parent p=new Child();
      

      已被声明为对父项的引用,而不是对子项的引用。这是合法的( Child 是 Parent ),但从变量 var 的角度来看,即使作为 Child 构造的对象也被视为 Parent,因此不考虑 Child 中写入的值。 如果变量 var 是在构造函数中定义的,情况将完全不同,方式如下

       class Parent {
      
          protected int var;
      
          Parent(){ var=11;}
      
          public Parent getInstance() {
              System.out.println("In Parent ...");
              return new Parent();
          }
      }
      
      class Child extends Parent {
      
          Child(){ var=22;}
      
          public Child getInstance() {
              System.out.println("In Child ...");
              return new Child();
          }
      }
      

      这一次使用相同的 main 函数,结果是 22,正如预期的那样,因为在 Parent 的 costuctor 中定义的值 11 被 Child 的 costuctor 中定义的值 22 覆盖。

      【讨论】:

        猜你喜欢
        • 2017-06-28
        • 1970-01-01
        • 1970-01-01
        • 2015-06-18
        • 2016-08-29
        • 2014-09-28
        • 1970-01-01
        • 2010-12-22
        • 1970-01-01
        相关资源
        最近更新 更多