多态复习笔记-4

构造器的调用顺序

package java_test1;
/*
 * 2019/7/23
 * 构造器与多态-构造器的调用顺序
 * */
class Meal{
	Meal(){
		System.out.println("Meal()");
	}
}
class Bread{
	Bread(){
		System.out.println("Bread()");
	}
}
class Cheese{
	Cheese(){
		System.out.println("Cheese()");
	}
}
class Lettuce{
	Lettuce(){
		System.out.println("Lettuce()");
	}
}
class Lunch extends Meal{
	Lunch(){
		System.out.println("Lunch()");
	}
}
class PortableLunch extends Lunch{
	PortableLunch(){
		System.out.println("PortableLunch()");
	}
}
public class Sandwich extends PortableLunch{
	private Bread b=new Bread();
	private Cheese c=new Cheese();
	private Lettuce l=new Lettuce();
	public Sandwich() {
		System.out.println("Sandwich()");
	}
	public static void main(String[] args) {
		new Sandwich();
	}
}
//output:
//Meal()
//Lunch()
//PortableLunch()
//Bread()
//Cheese()
//Lettuce()
//Sandwich()

只有基类构造器才有恰当的知识和权限来对自己的元素进行初始化,因此必须令所有的构造器都得到调用,否则就不能构造出完整的对象。这就是编译器强调每个导出类部分必须调用否早起的原因。
调用构造器遵循下面的顺序:
1)调用基类构造器。这个步骤会不断反复递归下去,首先是构造这种层次结构的根,然后是下一层导出类,直到底层导出类。
2)按声明顺序调用成员的初始化方法。
3)调用导出类的构造器主体。
调用顺序是很重要的,当进行继承时,我们知道基类的一切,并且可以访问基类中任何非private成员,必须假定基类中所有成员都是有效的。所以首先应该调用基类构造器,然后是确保本类的成员都得到初始化。