构造器的调用顺序 2016.12.8

复杂对象调用构造器遵照下面的顺序:

(1)调用基类构造器。这个步骤会不断地反复递归下去,首先是构造这种层次结构的额根,然后是下一层的导出类,直到最低层的导出类。

(2)按声明顺序调用成员的初始化方法。

(3)调用导出类构造器的主体。

下面这个例子就形象地说明了构造器的调用顺序。

Meal类:

package cn.qdu.exercise10;

class Meal {
    Meal(){
        System.out.println("Meal()");
    }
}

Bread类:

package cn.qdu.exercise10;

class Bread {
    Bread(){
        System.out.println("Bread()");
    }
}

cheese类:

package cn.qdu.exercise10;

class Cheese {
    Cheese(){
        System.out.println("Cheese()");
    }
}

lettuce类:

package cn.qdu.exercise10;

class Lettuce {
    Lettuce(){
        System.out.println("Lettuce()");
    }
}

Lunch类继承Meal类:

package cn.qdu.exercise10;

class Lunch extends Meal {
    Lunch(){
        System.out.println("Lunch()");
    }
}

protableLunch类继承lunch类:

package cn.qdu.exercise10;

class ProtableLunch extends Lunch {
    ProtableLunch(){
        System.out.println("ProtableLunch()");
    }
}

Sandwich类继承ProtableLunch类,它反映了三层继承。

package cn.qdu.exercise10;

public class Sandwich extends ProtableLunch {
    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();
    }
}

 

运行结果:

Meal()
Lunch()
ProtableLunch()
Bread()
Cheese()
Lettuce()
Sandwich()

分析:

先调用基类的构造器,再输出调用成员的构造方法,最后再执行Sandwich方法的主体。

同时在此发现了一个问题,构造方法本身没有返回值,不能加void,一旦加了void,那么构造方法就变成了普通方法,也无法被实例化。

例如:若在Bread类的构造方法前面加void,则在Sandwich.java中将无法对其实例化。

 

package cn.qdu.exercise10;

class Bread {
    void Bread(){
        System.out.println("Bread()");
    }
}

 

运行结果:

Meal()
Lunch()
ProtableLunch()
Cheese()
Lettuce()
Pickle()
Sandwich()

可见运行结果中没有出现Bread的实例化。

 

posted @ 2016-12-08 12:20  奋斗的蜗牛cn  阅读(245)  评论(0编辑  收藏  举报