1. 程式人生 > >java的繼承關係中,構造方法呼叫問題

java的繼承關係中,構造方法呼叫問題

原文: http://www.cnblogs.com/lanxuezaipiao/p/3371224.html

考慮下下面程式碼輸出結果

public class test3 {
    public static void main(String[] args) {
        new Child("mike");
    }
}
class People {
    String name;
    public People() {
        System.out.print(1);
    }
    public People(String name) {
        System.out.print(2);
        this.name = name;
    }
}

class Child extends People {
    People father;
    public Child(String name) {
        System.out.print(3);
        this.name = name;
        father = new People(name + ":F");
    }
    public Child() {
        System.out.print(4);
    }
}

答案在最後

下面是一個延伸題

public class Dervied extends Base {
    private String name = "dervied";
    public Dervied() {
        tellName();
        printName();
    }
    public void tellName() {
        System.out.println("Dervied tell name: " + name);
    }
    public void printName() {
        System.out.println("Dervied print name: " + name);
    }
    public static void main(String[] args){
        new Dervied();    
    }
}

class Base {
    private String name = "base";
    public Base() {
        tellName();
        printName();
    }
    public void tellName() {
        System.out.println("Base tell name: " + name);
    }
    public void printName() {
        System.out.println("Base print name: " + name);
    }
}

第一題答案:  132

解析:考察的又是父類與子類的建構函式呼叫次序。在Java中,子類的構造過程中必須呼叫其父類的建構函式,是因為有繼承關係存在時,子類要把父類的內容繼承下來。但如果父類有多個建構函式時,該如何選擇呼叫呢?

第一個規則:子類的構造過程中,必須呼叫其父類的構造方法。一個類,如果我們不寫構造方法,那麼編譯器會幫我們加上一個預設的構造方法(就是沒有引數的構造方法),但是如果你自己寫了構造方法,那麼編譯器就不會給你添加了,所以有時候當你new一個子類物件的時候,肯定呼叫了子類的構造方法,但是如果在子類構造方法中我們並沒有顯示的呼叫基類的構造方法,如:super(); 這樣就會呼叫父類沒有引數的構造方法。    

第二個規則:如果子類的構造方法中既沒有顯示的呼叫基類構造方法,而基類中又沒有無參的構造方法,則編譯出錯,所以,通常我們需要顯示的:super(引數列表),來呼叫父類有引數的建構函式,此時無參的建構函式就不會被呼叫。

總之,一句話:子類沒有顯示呼叫父類建構函式,不管子類建構函式是否帶引數都預設呼叫父類無參的建構函式,若父類沒有則編譯出錯。

第二題:

Dervied tell name: null
Dervied print name: null
Dervied tell name: dervied
Dervied print name: dervied

解析:

在第一題的基礎上,

子類的構造過程中必須呼叫其父類的建構函式,因為有繼承關係存在時,先父後子;

其次:子類可以訪問父類的非私有成員變數和非私有方法,但是父類不可以訪問子類的一切