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

Java构造器调用的层次结构带来了一个有趣的两难问题。如果在一个构造器的内部调用正在构造的对象的某个动态绑定方法,那会发生什么情况?

class Glyph{

	void draw(){System.out.println("Glyph.draw()");}

	Glyph()
	{
		System.out.print("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

Glyph.draw()  方法设计为将要被覆盖,这种覆盖是在RoundGlyph中发生的。 但是 Glyph.draw构造器会调用这个方法,结果导致了对RoundGlyph.draw()的调用,结果我们发现当Glyph的构造器调用draw()方法时, radius 不是默认初始值1 , 而是 0 。

因此,初始化的实际过程是:

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

(2)如前所述那样调用基类构造器。此时,调用被覆盖后的draw()方法( 在调用 RoundGlyph的构造器之前) ,由于步骤1的缘故,此时的radius的值为0

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

(4)调用导出类的构造器主体

所以,在编写构造器时有一条有效的准则:“ 用尽可能简单的方法使对象进入正常状态,如果可以的话,避免调用其他方法”

时间: 2024-10-11 02:27:05

Java构造器内部的多态方法的行为的相关文章

Java构造器内部的多态方法

本文主要详解java构造器内部的多态方法,更多Java技术知识,请登陆疯狂软件教育官网. 我们知道,动态绑定的调用是在运行时才决定的,对象无法知道到底调用的是哪个类的方法. 当我们在构造器中调用动态绑定的方法,就会用到该方法被覆盖之后的定义.但是这种调用的效果难以预计,因为被覆盖的方法在对象被完全构造之前就会被调用.我们先来看看下面这段代码: Java代码 class Base{ private String name = "base"; Base(){ tellName(); pri

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

每天发出自己学习的内容,坚持坚持... 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{

构造器内部的多态方法的行为详解(附源码)

前言 构造器调用的层次结构带来了一个有趣的两难问题.如果在一个构造器的内部调用正在构造的对象的某个动态绑定方法,那会发生什么情况呢?在一般的方法内部,动态绑定的调用是在运行时才决定的,因为对象无法知道它是属于方法所在的那个类,还是属于那个类的导出类. 如果要调用构造器内部的一个动态绑定方法,就要用到那个方法的被覆盖后的定义.然而,这个调用的效果可能相当难于预料,因为被覆盖的方法在对象被完全构造之前就会被调用.这可能会造成一些难于发现的隐藏错误. 从概念上讲,构造器的工作实际上是创建对象(这并非是

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

我们先来看一个例子,如果你读过<java编程思想>的话 应该会有印象 1 package com.test.zj; 2 3 public class PolyConstructors { 4 5 public static void main(String[] args) { 6 // TODO Auto-generated method stub 7 new RoundGlyph(5); 8 } 9 10 } 11 12 class RoundGlyph extends Glyph { 13

java构造器内部多态方法

/** * Created by Administrator on 2017/3/7. */ /** * @author zhenghong * @date 2017-03-07-21:21 **/public class TestC { public static void main(String []args) { new Graph(5); }}class Grp{ void draw() { System.out.println("draw...."); } Grp() { d

JAVA编程思想(4) - 多态(三)

若干个对象共享 例如Frog对象拥有其自己的对象,并且知道他们的存活多久,因为Frog对象知道何时调用dispose()去释放其对象.然而,如果这些成员对象中存在于其他一个或多个对象共享的情况,问题将不再简单,不再能简单的调用dispose()了.在这种情况下,我们也许需要引用计数来跟踪依旧访问着共享对象的数量. //: polymorphism/ReferenceCounting.java // Cleaning up shared member objects. import static

[Effective Java]考虑用静态工厂方法代替构造器

本文主要介绍如何使用静态工厂方法已经在那种场合来使用这种方式代替构造方法. 众所周知,对于类而言,我们为了获得一个类的实例对象,通常情况下会提供一个公有的(public) 的构造器.当然除了这种方法以外,我们还可以通过给类提供一个public的静态工厂方法(static factory method)的方式来完成,让它返回一个类的实例. 先看一个简单的Boolean的示例,这个示例将boolean基本类型值转换成一个Boolean对象的引用. public static Boolean valu

用.native修饰器来对外部组件进行构造器内部方法的调用以及用原生js获取构造器里的方法

html <div id="app"> <span v-text="number"></span> <btn @click.native="add(10,$event)"></btn> <button @click="add(10,$event)">add</button> </div> <button onclick=&qu

Java构造器和方法的区别(转自http://www.blogjava.net/weidagang2046/articles/3430.html)

摘要要学习Java,你必须理解构造器.因为构造器可以提供许多特殊的方法,这个对于初学者经常混淆.但是,构造器和方法又有很多重要的区别.原作者:Robert Nielsen 原站:www.javaworld.com 我们说构造器是一种方法,就象讲澳大利亚的鸭嘴兽是一种哺育动物.(按:老外喜欢打比喻,我也就照着翻译).要理解鸭嘴兽,那么先必须理解它和其他哺育动物的区别.同样地,要理解构造器,那么就要了解构造器和方法的区别.所有学习java的人,尤其是对那些要认证考试的,理解构造器是非常重要的.下面将