super(...) 或隱式 super()(無參)。public class InheritanceDemo {
public static void main(String[] args) {
// SubClass sc = new SubClass(); // 若父類無無參構造器,這行編譯錯誤
SubClass sc2 = new SubClass(200);
sc2.eat();
}
static class SuperClass {
private int n;
SuperClass() {
System.out.println("SuperClass() 無參構造器");
}
SuperClass(int n) {
System.out.println("SuperClass(int n): " + n);
this.n = n;
}
void eat() { System.out.println("SuperClass eat"); }
}
static class SubClass extends SuperClass {
private int n;
SubClass() {
// super(300); // 若父類無無參構造器,必須取消註釋顯式調用
System.out.println("SubClass() 無參構造器");
}
SubClass(int n) {
// super(300); // 同理
System.out.println("SubClass(int n): " + n);
this.n = n;
}
}
}
SuperClass(int n): 200
SubClass(int n): 200
調用 new SubClass(200) 時:
SubClass(int n) 首行隱式調用 super()(因父類有無參構造器)SuperClass() 執行,打印無參信息若父類移除無參構造器,子類構造器必須首行寫 super(參數),否則編譯錯誤:Implicit super constructor SuperClass() is undefined. Must explicitly invoke another constructor。
new SubClass(200) │ ├─ 1. 分配 SubClass 對象內存(含繼承自 SuperClass 的字段 n) │ ├─ 2. 默認初始化:所有字段賦 0/null/false │ ├─ 3. 執行父類構造器鏈 │ ├─ SuperClass() / SuperClass(int n) ← 此處決定調用哪個 │ ├─ 父類字段顯式初始化 / 實例初始化塊 │ └─ 父類構造器體代碼 │ ├─ 4. 子類字段顯式初始化 / 實例初始化塊 │ └─ 5. 子類構造器體代碼執行完畢,返回引用
| 誤區 | 正確認知 |
|---|---|
| 子類繼承了父類構造器 | 構造器非成員,不參與繼承;子類通過 super 調用父類構造邏輯 |
| super() 可以寫在構造器任意位置 | 必須是構造器第一條語句,前面不能有任何代碼 |
| this() 和 super() 可以共存 | 互斥,二選一,且必須首行 |
| 父類無無參構造器,子類不寫構造器也能編譯 | 子類隱式無參構造器會調用 super(),編譯失敗 |
super(...),部分初始化自身字段。掌握構造器調用鏈,是寫出健壯繼承體系、避免「脆弱基類問題」的基石。