创建基类对象时的运行时多态性

时间:2015-05-19 10:00:41

标签: java

请考虑以下代码。

class Base{
  Base() {  
      print();   
  }
  void print() { 
      System.out.println("Base"); 
  }
}

class Child extends Base{
   int i =   4;
   public static void main(String[] args){
      Base base = new Child();
      base.print();
   }
   void print() { 
       System.out.println(i); 
   }
}

程序将打印0,4。

我理解的是,将根据实际对象的类选择要执行的方法,因此在这种情况下为Child。因此,当调用Base的构造函数时,会调用Child的打印方法,因此将打印0,4。

请告诉我是否理解正确吗? 如果是,我还有一个问题,而基类构造函数正在运行JVM如何调用Child的方法,因为Child的对象未被创建?

2 个答案:

答案 0 :(得分:7)

  

[...]将根据实际对象的类别选择要执行的方法

是的,您的理解是正确的:根据正在创建的对象的类型选择方法,因此呼叫将发送到Child.print()而不是Base.print()

  

Base类构造函数正在运行时,JVM如何调用Child的方法,因为Child的对象未创建?

Base的构造函数正在运行时,Child对象已经创建。但是,它未完全初始化。这正是避免调用可以在构造函数内部覆盖的方法的原因:语言允许它,但程序员在执行时应该格外小心。

有关基类构造函数调用可覆盖方法时可能发生的问题的更多信息,请参阅this Q&A

答案 1 :(得分:0)

  

将根据实际对象的类别选择要执行的方法

是的,这是正确的。

  

Base base = new Child();

。它不会以你认为它while Base class constructor is running how come JVM can call Child's method since Child's object is not created?的方式发生。 这里发生的是,Child实例被创建,而Child实例是通过Child的默认构造函数创建的,它首先调用超级构造函数that is where the 0 get printed