`
paddy.w
  • 浏览: 498073 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

 
阅读更多
        首先明确一点:Java中除了static方法和final方法(private方法属于final方法)之外,其他所有的方法都是动态绑定的。

        设想这样一个场景:在父类的构造器中调用一个动态绑定方法(假设叫做A),其子类重写了A方法,然后生成子类对象(目的是调用构造器),会发生什么?来看下面一个例子:
public class Test{

	public static void main(String[] args) {
		new B(5);
	}
}

class A{
	void draw(){
		System.out.println("A.draw()");
	}
	A(){
		System.out.println("A() before draw()");
		draw();
		System.out.println("A() after draw()");
	}
}

class B extends A{
	private int radius =1;
	public B(int r) {
		System.out.println("after the base constructor:"+radius);
		radius=r;
		System.out.println("B.B(), radius="+radius);
	}
	void draw(){
		System.out.println("B.draw(), radius="+radius);
	}
}


        会出现什么结果?
A() before draw()
B.draw(), radius=0
A() after draw()
after the base constructor:1
B.B(), radius=5


        调用父类构造器时,动态绑定的draw方法实际执行的是子类的draw。如果程序运行到构造器的内部,那么整个对象可能只是部分形成。这里可能造成的一个假象是:非静态成员变量的初始化发生在构造方法执行之后。这样说的理由可能是在构造器内部输出的radius的值为0。但是需要注意,radius是属于B的非静态成员变量,B.draw(), radius=0的输出结果发生在B的构造方法执行之前,这条语句是B父类的构造器输出的。after the base constructor:1才是B构造器执行的第一条语句,也是构造方法执行的一个标志,这时radius已经被初始化为1。
        从这个例子可以得到的结论是:一个动态绑定的方法调用会向外深入到继承层次结构内部,它可以调用子类里的方法。如果我们在构造器内部这样做,那么就可能会调用某个方法,而这个方法所操纵的成员可能还未进行初始化。
            这个例子所展示的初始化实际过程是:
  • 在其他任何食物发生之前,将分配给对象的存储空间初始化成二进制的0
  • 调用父类的构造器,父类构造器中的draw方法实际执行的是子类重写过的draw
  • 按照声明的顺序调用成员的初始化方法
  • 调用子类的构造器

        编写构造器的一条准则是:用尽可能简单的方法使对象进入正常状态;如果可以的话,避免调用其他方法。
        在构造器内唯一能够安全调用的那些方法是父类中的final方法,因为这写方法不能被覆盖。
分享到:
评论

相关推荐

    Java中构造器内部的多态方法的行为实例分析

    主要介绍了Java中构造器内部的多态方法的行为,结合实例形式分析了java构造器内部多态方法相关原理、功能及操作技巧,需要的朋友可以参考下

    C++编程思想习题

    8.3.3在构造函数和析构函数里隐藏行为 8.4减少混乱 8.5预处理器的特点 8.6改进的错误检查 8.7小结 8.8练习 第9章 命名控制 9.1来自C语言中的静态成员 9.1.1函数内部的静态变量 9.1.2控制连接 9.1.3其他的存储类型...

    CLR.via.C#.(中文第3版)(自制详细书签)Part2

    18.3 attribute的构造器和字段/属性的数据类型 18.4 检测定制attribute 18.5 两个attribute实例的相互匹配 18.6 检测定制attribute时不创建从Attribute派生的对象 18.7 条件attribute类 第19章 可空值类型 ...

    javaSE代码实例

    10.4.1 构造器的调用流程及默认构造器 182 10.4.2 自定义构造器需要注意的问题 185 10.4.3 不能继承构造器 186 10.4.4 调用兄弟构造器 187 10.5 单列模式 189 10.6 Java程序的加载过程 190 10.7 小结 ...

    CLR.via.C#.(中文第3版)(自制详细书签)Part1

    18.3 attribute的构造器和字段/属性的数据类型 18.4 检测定制attribute 18.5 两个attribute实例的相互匹配 18.6 检测定制attribute时不创建从Attribute派生的对象 18.7 条件attribute类 第19章 可空值类型 ...

    CLR.via.C#.(中文第3版)(自制详细书签)

    18.3 attribute的构造器和字段/属性的数据类型 18.4 检测定制attribute 18.5 两个attribute实例的相互匹配 18.6 检测定制attribute时不创建从Attribute派生的对象 18.7 条件attribute类 第19章 可空值类型 ...

    CLR.via.C#.(中文第3版)(自制详细书签)Part3

    18.3 attribute的构造器和字段/属性的数据类型 18.4 检测定制attribute 18.5 两个attribute实例的相互匹配 18.6 检测定制attribute时不创建从Attribute派生的对象 18.7 条件attribute类 第19章 可空值类型 ...

    java经典面试2010集锦100题(不看你后悔)

    C) 子类继承父类,如果父类中只有一个构造方法并且有参数,那么在子类的构造方法中必须先用super调用父类构造方法并传参。 D) 以上说法都不正确。 题目11:d 程序如下: class Test { private int day; public int...

    net学习笔记及其他代码应用

    答:构造器Constructor不能被继承,因此不能重写Overriding,但可以被重载Overloading。 42.是否可以继承String类? 答:String类是final类故不可以继承。 43.try {}里有一个return语句,那么紧跟在这个try后的...

    AIC的Java课程1-6章

    第4章 面向对象(封装) 4课时  理解类封装属性(数据成员)和行为(方法成员),区别类和对象。  能够定义类,创建类的对象(实例化类)和通过对象引用访问数据成员和方法成员;形成定义类和使用类...

    Scala程序设计(第2版)

    8.8 调用父类构造器(与良好的面向对象设计) 226 8.9 嵌套类型 230 8.10 本章回顾与下一章提要 232 第9章 特征 233 9.1 Java 8中的接口 233 9.2 混入trait 234 9.3 可堆叠的特征 238 9.4 ...

    C++ 语言 详细教程电子版

    内容涉及对象的演化、数据抽象、隐藏实现、初始化与清除、函数重载与缺省参数、输入输出流介绍、常量、内联函数、命名控制、引用和拷贝构造函数、运算符重载、动态对象创建、继承和组合、多态和虚函数、模板和包容器...

    C++编程思想

    内容涉及对象的演化、数据抽象、隐藏实现、初始化与清除、函数重载与缺省参数、输入输出流介绍、常量、内联函数、命名控制、引用和拷贝构造函数、运算符重载、动态对象创建、继承和组合、多态和虚函数、模板和包容器...

    C编程思想--chinapub书籍--文本PDF

    内容涉及对象的演化、数据抽象、隐藏实现、初始化与清除、函数重载与缺省参数、输入输出流介绍、常量、内联函数、命名控制、引用和拷贝构造函数、运算符重载、动态对象创建、继承和组合、多态和虚函数、模板和包容器...

    c++学习经典图书:C++ 编程思想(全).rar

    内容涉及对象的演化、数据抽象、隐藏实现、初始化与清除、函数重载与缺省参数、输入输出流介绍、常量、内联函数、命名控制、引用和拷贝构造函数、运算符重载、动态对象创建、继承和组合、多态和虚函数、模板和包容器...

    C++编程思想(中文版)

    内容涉及对象的演化、数据抽象、隐藏实现、初始化与清除、函数重载与缺省参数、输入输出流介绍、常量、内联函数、命名控制、引用和拷贝构造函数、运算符重载、动态对象创建、继承和组合、多态和虚函数、模板和包容器...

    C++编程思想——很实用的一本书

    动态对象创建、继承和组合、多态和虚函数、模板和包容器类、多重继承、异常处理和运行时类型识别。 本书作为正式教材和自学用书均非常优秀,作为程序设计者的参考用书亦极为合适。 目 录 译者序 前言 第1章 对象的...

    thinking in C++

    内容涉及对象的演化、数据抽象、隐藏实现、初始化与清除、函数重载与缺省参数、输入输出流介绍、常量、内联函数、命名控制、引用和拷贝构造函数、运算符重载、动态对象创建、继承和组合、多态和虚函数、模板和包容器...

Global site tag (gtag.js) - Google Analytics