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

一.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\n"); }
6 Base() {
7 draw();
8 }
9 };
10
11 class Derive:public Base {
12 public:
13 //@Override
14 void draw() { printf("Derive draw, id = %d\n", id); };
15 private:
16 int id = 1;
17 };
18
19 int main()
20 {
21 new Derive();
22 return 0;
23 }

[Java]构造函数内部多态的行为所引起的灾难的更多相关文章

  1. java 构造函数内部的多态方法 完全剖析

    我们先来看一个例子,如果你读过<java编程思想>的话 应该会有印象 package com.test.zj; public class PolyConstructors { public ...

  2. java构造器内部多态方法

    public class TestC { public static void main(String []args) { new Graph(5); }}class Grp{ void draw() ...

  3. Java基础之多态和泛型浅析

    Java基础之多态和泛型浅析 一.前言: 楼主看了许多资料后,算是对多态和泛型有了一些浅显的理解,这里做一简单总结 二.什么是多态? 多态(Polymorphism)按字面的意思就是“多种状态”.在面 ...

  4. java中实现多态的机制是什么?

    多态性是面向对象程序设计代码重用的一个重要机制,我们曾不只一次的提到Java多态性.在Java运行时多态性:继承和接口的实现一文中,我们曾详细介绍了Java实现运行时多态性的动态方法调度:今天我们再次 ...

  5. Java开发知识之Java的继承多态跟接口*

    Java开发知识之Java的继承多态跟接口 一丶继承 1.继承的写法 在Java中继承的 关键字是 extends 代表一个类继承另一个类. 继承的含义以及作用: 继承就是基于某个父类的扩展.制定出来 ...

  6. Java 继承和多态

                                                        Java  继承和多态 Java 继承 继承的概念 继承是java面向对象编程技术的一块基石,因 ...

  7. Java类的多态机制

    Java中将一个方法调用同一个方法主体关联起来被称作绑定. 绑定分为前期绑定和后期绑定.前期绑定是在编译器决定的,而后期绑定是在程序运行时决定的.Java中除了static方法和final方法(pri ...

  8. 通过实例聊聊Java中的多态

    Java中的多态允许父类指针指向子类实例.如:Father obj=new Child();  那么不禁要发问?? 使用这个父类型的指针访问类的属性或方法时,如果父类和子类都有这个名称的属性或方法,哪 ...

  9. Java对象和多态

    Java对象和多态 (面向对象) 面向对象基础 面向对象程序设计(Object Oriented Programming) 对象基于类创建,类相当于一个模板,对象就是根据模板创建出来的实体(就像做月饼 ...

随机推荐

  1. hdu 4542 小明系列故事——未知剩余系 反素数 + 打表

    小明系列故事——未知剩余系 Time Limit: 500/200 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Prob ...

  2. 常用的SQL 总结

    1.去重 SELECT * FROM my where id in(SELECT MAX(id) from my GROUP BY id,iid,pid)//取 id,iid,pid重复的最大值

  3. GridView内容详解(转载)

    GridView内容详解(转载) GridView是ASP.NET界面开发中的一个重要的控件,对GridView使用的熟练程度直接影响软件开发的进度及功能的实现.(车延禄)GridView的主要新特性 ...

  4. DbHelperSQL 事务写法!

    try { DBUtility.CommandInfo dbcom = new DBUtility.CommandInfo(); List<DBUtility.CommandInfo> s ...

  5. 山东省第七届ACM省赛

    ID Title Hint A Julyed 无 B Fibonacci 打表 C Proxy 最短路径 D Swiss-system tournament 归并排序 E The Binding of ...

  6. phpStudy如何修改端口及WWW目录

    phpStudy如何修改端口及WWW目录 phpStudy如何修改端口 请使用『其他选项菜单』-『phpStudy设置』-『端口常规设置』.

  7. Git_学习_01_ 常用 Git 命令清单

    我每天使用 Git ,但是很多命令记不住. 一般来说,日常使用只要记住下图6个命令,就可以了.但是熟练使用,恐怕要记住60-100个命令. 下面是我整理的常用 Git 命令清单.几个专用名词的译名如下 ...

  8. freeMarker(一)——freeMarker简介

    学习笔记,选自freeMarker中文文档,译自 Email: ddekany at users.sourceforge.net FreeMarker简介: FreeMarker 是一款 模板引擎: ...

  9. 让网站变灰的CSS代码(支持IE、FIREFOX和CHROME)(转)

    方法1:支持IE <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xht ...

  10. [转]CSS遮罩——如何在CSS中使用遮罩

    特别声明:此篇文章由D姐根据Christian Schaefer的英文文章原名<CSS Masks – How To Use Masking In CSS Now>进行翻译,整个译文带有我 ...