zoukankan      html  css  js  c++  java
  • [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 }

  • 相关阅读:
    MFC 将文件拖进对话框获得文件信息
    微软历史最高市值是多少?
    ZooKeeper的学习与应用
    OutputCache祥解
    本人的微博转移
    java list三种遍历方法性能比較
    VS2010旗舰版安装图解
    SSL协议具体解释
    freemarker字符串拼接
    [java web 入门](一)MyEclipse &amp; HelloWorld 记录
  • 原文地址:https://www.cnblogs.com/brianyi/p/6544137.html
Copyright © 2011-2022 走看看