当前位置:首页 > 开发 > 编程语言 > 编程 > 正文

构造器内部的多态方法的行为

发表于: 2014-08-15   作者:刘小瘦   来源:转载   浏览:
摘要: 今天,看到《Thinking in Java》中文版中的P162构造器内部的多态方法的行为。中文版啊,前面的两段话我表示很无语。 原话如下: 如果要调用构造方法内部的一个动态绑定方法,就要用到那个方法的被覆盖后的定义。然而这个调用的效果可能相当难以预料,因此被覆盖的方法在对象被完全构造之前就会被调用。这可能会造成一些难于发现的隐藏错误。   从概念上讲,构造方法的工作实际上是创建对
今天,看到《Thinking in Java》中文版中的P162构造器内部的多态方法的行为。中文版啊,前面的两段话我表示很无语。
原话如下:
如果要调用构造方法内部的一个动态绑定方法,就要用到那个方法的被覆盖后的定义。然而这个调用的效果可能相当难以预料,因此被覆盖的方法在对象被完全构造之前就会被调用。这可能会造成一些难于发现的隐藏错误。
  从概念上讲,构造方法的工作实际上是创建对象。在任何构造方法内部,整个对象可能只是部分形成--我们知道基类已经进行初始化。如果构造方法只是在构建对象过程中的一个步骤,并该对象所属于的类是从构造方法所属的类导出的,那么导出部分在当前构造方法被调用的时刻仍旧是没有被初始化的。然而,一个动态绑定的方法调用却会向外深入到继承层次结构内部,它可以调用子类里的方法。如果我们是在构造方法内部这样做,那么就可能会调用某个方法,而这个方法所操纵的成员可能还未进行初始化。---这肯定会招致灾难。

代码如下:
 
class Glyph{
    void draw(){ 
        System.out.println("Glyph.draw()"); 
    } 
     
    Glyph(){ 
        System.out.println("Glyph() before draw()"); 
        draw();
        System.out.println("Glyph() after draw()"); 
    } 

 
class RoundGlyph extends Glyph{
    private int radius = 1; 
    RoundGlyph(int r){ 
        radius = r; 
        System.out.println("RoundGlyph.RoundGlyph(),  radius = " + radius);
    } 
    void draw(){ 
        System.out.println("RoundGlyph.draw()  radius = " + radius); 
    } 

 
public class PolyConstructors { 
    public static void main(String [] args){ 
        new RoundGlyph(5); 
    } 
}  

结果如下:
Glyph() before draw() 
RoundGlyph.draw()  radius = 0 
Glyph() after draw() 
RoundGlyph.RoundGlyph(),  radius = 5 

我的理解是:之所以这可能不是我们想要的结果,是因为我们没有真实认识到类的初始化的实际过程。
对于类的初始化过程,我原先的理解是:
1) 调用基类构造函数,初始化基类。
2)按声明顺序调用成员的初始化方法。
3)调用导出类构造器的主体。
而错误的原因正是在调用任何函数之前,在堆栈中已经为你new的对象类分配了存储空间并进行了初始化。
下面就是《Thinking in Java》对此问题的总结

初始化的实际过程是:
1.在其他任何事物发生之前,将分配给对象的存储空间初始化成二进制的零。
2.如前所述那样调用基类构造器,此时,调用被覆盖后的draw()方法(注意,要在调用RoundGlyph构造器之前调用),由于步骤1 的缘故,我们此时会发现radius的值为0。
3.按照声明的顺序调用成员的初始化方法。
4调用导出类的构造器主体。
这样做有一个优点,那就是所有东西都至少初始化为零(或者是某些特殊数据类型中与“零”等价的值)而不是仅仅留作垃圾。其中包括通过组合而嵌入一个类内部的对象引用,其值是null,如果忘记为该引用进行初始化,就会在运行时throw NULLPointException。
有一句话很经典:“用尽可能简单的方法使对象进入正常状态,如果可以的话,避免调用其他方法”。
在构造器内唯一能够安全调用的那些方法是基类的final方法。

构造器内部的多态方法的行为

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
我们说构造器是一种方法,就象讲澳大利亚的鸭嘴兽是一种哺育动物。(按:老外喜欢打比喻,我也就照着
在方法与数据成员中,我们提到,Java中的对象在创建的时候会初始化(initialization)。初始化时,对
最近做一个项目,使用了一个抽象类的线程类,使用的时候发现有时会出现调用纯虚函数的情况,代码如
各位仁兄,前几日我在项目中写了类似这么一段代码 AbstractClass package com.my.study; public abs
1.Class类---Class类是反射的基石,Class类的实例表示正在运行的java应用程序中的接口或类。换句话
8.1实例构造器和类(引用类型) 8.2实例构造器和结构(值类型) 8.3类型构造器 8.4操作符重载 8
构造方法内容会多一些,涉及Swift中构造的一些规则与概念。这次写了7个Person来复习,外加名人XiaoM
主构造器与私有构造器 package kmust.hjr.learningScala08 /** * Created by Administrator on 2015
abap 构造方法是由运行时环境自动调用的,一般用于初始化操作,不能在程序中由程序调用,系统通常会
可以用构造器来进行初始化。在运行时刻,可以调用方法或执行某些动作来确定初值,这为编程带来了更大
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号