JAVA中构造器内部的多态方法行为。我们知道JAVA中存在继承的时候,构造的一个导出类的对象时总是会先调用基类的构造方法。当我们在导出类中覆盖基类的某个方法,再把一个导出类对象的引用向上转型为基类引用的时候,我们使用这个引用调用该方法,结果使用出来的还是导出类的方法,这时JAVA中的动态斑绑定(多态)实现的。那么,就有一个问题了,如果这个多态时套基类的构造器中呢?这时候会发生什么?话不多说,直接实验一下:

package chapter8;
import static net.mindview.util.Print.*;

class Base{
	void draw(){
		print("Base's draw method was called");
	}
	Base(){
		print("Before Base's draw method was called");
		draw();
		print("After Base's draw method was called");
	}
}

class Inher extends Base{
	int para=1;
	Inher(int para){
		this.para=para;
		print("Inher's para was "+para);
	}
	@Override void draw(){
		print("Inher's draw ,para is "+para);
	}
}

public class P163 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Inher a=new Inher(5);
		a.draw();
	}

}
运行结果:
Before Base's draw method was called
Inher's draw ,para is 0
After Base's draw method was called
Inher's para was 5
Inher's draw ,para is 5

在上面的代码中,我们的基类也有一个draw方法,但是从运行结果来看,这个基类的draw方法压根就被有被调用过。我们Inher a=new Inher(5);这时候最先调用的是基类Base的构造方法:
于是先打印出:Before Base’s draw method was called。然后是draw方法的调用,这是在Base类也就是基类构造器中调用draw方法,但是不要忘了,这次调用的出发点是a,a是一个Inher导出类对象,而导出类已近重写了draw方法。所以这时候调用的还是Inher中的draw方法,这是就要打印para的值,我们可以看到打印出来的是0,这就很很奇怪了,既不是我们在Inher类的para初始化设定的1,也不是Inher构造器中传入的值5。为什么会出现这样的情形?这牵扯到子类构造的过程:1调用基类的构造器。2按照申明的顺序调用成员的初始化。3调用自身的构造器方法。
我们在基类的构造器中调用draw,而这时候还处在上面三个阶段的第一阶段,这时候para=1还没有执行。申请来的地址空间再被分配给我们的时候,已近被初始化为一片二进制的0,所以这时候para的存放地址也是一片0,所以这时候打印出来就是0。而后para经济阶段2,值变成1,最后经历Inher的构造器,变成5.为了捕捉这个变成1的阶段,我们可以修改代码:

package chapter8;
import static net.mindview.util.Print.*;

class Base{
	void draw(){
		print("Base's draw method was called");
	}
	Base(){
		print("Before Base's draw method was called");
		draw();
		print("After Base's draw method was called");
	}
}

class Inher extends Base{
	int para=1;
	Inher(int para){
		print("Inher's para was "+this.para);
		this.para=para;
		print("Inher's para was "+this.para);
	}
	@Override void draw(){
		print("Inher's draw ,para is "+para);
	}
}

public class P163 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Inher a=new Inher(5);
		a.draw();
	}

}
运行结果:
Before Base's draw method was called
Inher's draw ,para is 0
After Base's draw method was called
Inher's para was 1
Inher's para was 5
Inher's draw ,para is 5

我们可以看到para是经历1这个阶段的。这也印证了上面导出类构造三阶段过程的说法。