public class Constraction_Test {
/**
* 在java中用子类去创建一个对象的时候会首先调用父类的无参构造函数
* 然后再去调用自己的构造函数
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new Sanwich();
}
}
class A{
A(){
System.out.println("A()");
}
}
class B{
B(){
System.out.println("B()");
}
}
class C{
C(){
System.out.println("C()");
}
}
class Meal{
Meal(){
System.out.println("Meal()");
}
}
class Lunch extends Meal{
Lunch(){
System.out.println("Lunch()");
}
}
class ProtableLunrch extends Lunch{
ProtableLunrch(){
System.out.println("ProtableLunrch()");
}
}
class Sanwich extends ProtableLunrch{
private A a = new A();
private B b = new B();
private C c = new C();
//以上三个实例放在构造函数的前面和后面对程序的运行效果不影响
Sanwich(){
System.out.println("Sanwich()");
}
}
当在main方法里新建一个Sanwich对象时,jvm发现了程序建立一个Sanwich里面,找到构造函数构造一个Sanwich对象,
但jvm发现Sanwich是ProtableLunrch的子类,所以构造函数会去构造ProtableLunrch的对象,但jvm发现ProtableLunrch
是Lunch的子类,。。。。依次类推。但是程序中有A,B,C类的变量,如果在Sanwich中没有实例化的话程序到此结束但
由于实例化了,所以在构造Sanwich的对象之前,要处理这三个变量
这里是输出的结果:
Meal()
Lunch()
ProtableLunrch()
A()
B()
C()
Sanwich()
另外一个例子
因为你的父类已经定义了一个有参的构造器,此时编译器不会为你调用默认的构造器,当子类继承时,必须在自己的构造函数显示调用父类的构造器,自己才能确保子类在初始化前父类会被实例化,如果你父类中有无参的构造器,字类就不会强制要求调用,即你写的那个就可以通过,编译器会默认帮你调用父类的构造器。
class E{
E(int a){
System.out.println("E()");
}
}
class F extends E{
F(int i ){
super(i);
//如果注释掉super(i)这一句,编译时就会出错。而却super的调用必须放在程序的第一句。
System.out.println("F()");
}
}