构造器的调用顺序:
step1: 调用基类构造器,首先是根,然后是下一层的导出类,直至最底层的导出类。
step2:按声明顺序调用成员的初始化方法。
step3:调用导出类构造器的主体。
还是用代码说明吧:
/**
* 构造器的调用顺序
*/
package sandwich;
import static org.print.Print.*;//自己写的print包
class Meal {
Meal() { print("Meal()"); }
}
class Bread {
Bread() { print("Bread()"); }
}
class Cheese {
Cheese() { print("Cheese()"); }
}
class Lettuce {
Lettuce() { print("Lettuce()"); }
}
class Pickle{
Pickle(){print("Pickle()");}
}
class Lunch extends Meal {
Lunch() { print("Lunch()"); }
}
class PortableLunch extends Lunch {
PortableLunch() { print("PortableLunch()");}
}
public class Sandwich extends PortableLunch {
private Bread b = new Bread();
private Cheese c = new Cheese();
private Lettuce l = new Lettuce();
public Sandwich() { print("Sandwich()"); }
public static void main(String[] args) {
new Sandwich();
}
private Pickle p=new Pickle();
}
上述代码的运行结果:
Meal()
Lunch()
PortableLunch()
Bread()
Cheese()
Lettuce()
Pickle()
Sandwich()
然鹅,当在构造器中创建了一个对象,但是该对象的所属的类是导出类。 因为在初始化对象,调用对象的构造器的时候,导出类并没有初始化。 。。。
还是用代码说明吧:
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; //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 // radius是0!
Glyph() after draw()
RoundGlyph.RoundGlyph(), radius = 5
so, RoundGlyph.draw() 覆盖了Glyph().draw() 的方法,但是,基类构造器在导出类构造器调用之前调用,所以此时radius 的值为0;
也就是说,完整的实例化的实际过程应该是:
1,在其他任何事物发生以前,将分配给对象的存储空间初始化为二进制的0;
2,如之前所述的那样,调用基类构造器。(第二个代码中,)
3,按照声明的顺序调用成员的初始化方法。调用覆盖后的draw()方法,但是RoundGlyph并未调用,radius 值为0;
4,调用导出类的构造器主体。