[Java]构造函数内部多态的行为所引起的灾难

构造函数内部的多态行为所产生的意想不到的结果

一.Java版本

 1 package com.company;
 2 import static com.brianyi.util.Print.*;
 3 
 4 class Base {
 5     void draw() { println("Base draw"); }
 6     Base() {
 7         draw();
 8     }
 9 }
10 
11 class Derive extends Base{
12     @Override
13     void draw() { println("Derive draw, id = " + id); }
14     private int id = 1;
15 }
16 
17 public class Main {
18     public static void main(String[] args)
19     {
20         new Derive();
21     }
22 }

从概念上讲,构造函数的工作实际上是创建对象,由于构造函数的调用时由内到外的,首先会调用Base(),由于派生类Derive重写了draw方法,因此Base()内部会调用派生类Derive的draw(),而实际上Derive的id会为0(这与Java初始化的过程有关)。

Java初始化的实际过程是:

1)在其他任何事物发生之前,将分配给对象的存储空间初始化为二进制0。

2)调用基类构造函数。这个步骤会不断的反复递归下去,首先是这种类层次结构的根类,然后是下一层的派生类(导出类),等等,直到最低层的派生类。

3)按声明顺序调用成员的初始化方法。

4)调用导出类的构造函数的主体。

二.C++版本

 1 #include <stdio.h> 
 2 
 3 class Base {
 4 public:
 5     void draw() { printf("Base draw
"); }
 6     Base() {
 7         draw();
 8     }
 9 };
10 
11 class Derive:public Base {
12 public:
13     //@Override
14     void draw() { printf("Derive draw, id = %d
", id); };
15 private:
16     int id = 1;
17 };
18 
19 int main()
20 {
21     new Derive();
22     return 0;
23 }

原文地址:https://www.cnblogs.com/brianyi/p/6544137.html