话不多说,先看一个例子:
public class Constructor extends Child
{
public Constructor()
{
System.out.println("Constructor()");
}
private Bread b=new Bread();
private int i=1;
void draw()
{
System.out.println("Constructor.draw() i="+i);
}
public static void main(String[] args)
{
new Constructor();
}
}
class Bread
{
public Bread()
{
System.out.println("Bread()");
}
}
class Father
{
void draw()
{
System.out.println("Father.draw()");
}
public Father()
{
System.out.println("Father() before draw");
draw();
System.out.println("Father() after draw");
}
}
class Child extends Father
{
void draw()
{
System.out.println("Child.draw()");
}
public Child()
{
System.out.println("Child()");
}
}
Father() before draw
Constructor.draw() i=0
Father() after draw
Child()
Bread()
Constructor()
注意观察输出结果的第二行,调用的实际是Constructor的draw方法,而且,i等于0,不等于1。
(1)构造函数中调用其他方法也会出现多态。调用的方法的被派生类覆盖的方法。然而,这种情况并不多见,在编写构造器时,我们遵循这样的原则:“用尽可能简单的方法使对象进入正常状态;可以的话,避免调用其他方法”。在构造器中唯一能安全调用的是那些方法时基类中的final方法(也适用于private方法,它们自动属于final方法)。这些方法不会被覆盖,因此不会出现“多态”的问题。
(2)初始化的实际过程是:
1)在其他任何事物发生之前,将分配给对象的存储空间初始化为二进制的零。
2)调用基类构造器。这个过程不断持续,直到最底层的导出类。
3)按照声明的顺序调用成员变量的初始化方法。
4)调用导出类构造器的主体。