簡體   English   中英

即使子類已經有一個已定義的構造函數,父類是否總是需要一個默認或無參數的構造函數?

[英]Does a parent class always need a default or no-argument constructor even if the child class already has a defined constructor?

我無法編譯這段代碼。

class Horse {
    private int age;
    Horse(int age) {
        this.age = age;
    }
}

class Pony extends Horse {
    private int age;
    Pony(int age) { //here compiler complains about no default constructor in parent class
        this.age = age;
    }
}

我知道當父類只有帶參數的構造函數時,你必須為子類定義一個構造函數,這就是我所做的。 但是,編譯器抱怨父類沒有默認構造函數。

我是否正確地得出結論父類總是需要默認或無參數構造函數? 如果我希望父類和子類只包含帶參數的構造函數,該怎么辦?

我是否正確地得出結論父類總是需要默認或無參數構造函數?

不。子類構造函數必須做的第一件事是調用其中一個超類構造函數。 如果不這樣做,那么編譯器會為您調用超類的no-arg構造函數。 但是,如果超類沒有超級類,那當然會失敗。

你的代碼應該是:

class Pony extends Horse {
    Pony(int age) {
        super(age);
    }
}

請參閱,超類已經有一個age字段,可能還有使用該字段的方法。 因此,在子類中重新聲明一個是錯誤的並且適得其反。

要使它編譯到你需要調用super(int)而不是隱式調用super()

Pony(int age) {
    super(age);
    this.age = age;
}

然后您可能會注意到HorsePony都具有完全相同的字段,其中包含完全相同的數據。 為什么Pony需要有領域age ,如果類Pony是基於( Horse )已定義這個領域?

Pony(int age) {
    super(age);
}

這是繼承之美:你可以利用已經在基類中編寫的任何東西。


但是,編譯器抱怨父類沒有默認構造函數。

它抱怨是因為,正如我上面提到的,它無法調用super()

如果構造函數體不以顯式構造函數調用開始並且聲明的構造函數不是原始類Object的一部分,那么構造函數體隱式地以超類構造函數調用“super();”開頭,這是對構造函數的調用。它的直接超類不帶參數。

https://docs.oracle.com/javase/specs/jls/se12/html/jls-8.html#jls-8.8.7


如果我希望父類和子類只包含帶參數的構造函數,該怎么辦?

然后子類應該始終顯式地聲明它想要調用的父構造函數。


我是否正確地得出結論父類總是需要默認或無參數構造函數?

不,沒有默認構造函數的父類是沒關系的,只要它的子元素不調用super()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM