首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 入門教學 (13):繼承中的建構子鏈 - super() 呼叫機制完整解析

     編輯:Java 相關知識

核心鐵律:子類建構子必先呼叫父類建構子

「子類物件包含父類部分」,初始化時必須先完成父類初始化。JVM 強制每個子類建構子的第一行執行父類建構子。

三種呼叫情境

1. 隱式呼叫無參建構子 (最常見、最危險)

class Employee {
    public Employee() { System.out.println("Employee()"); }
}

class Trainer extends Employee {
    public Trainer() { 
        // 編譯器自動插入 super(); 
        System.out.println("Trainer()"); 
    }
}

// new Trainer() 輸出:
// Employee()
// Trainer()

⚠️ 前提:父類必須有無參建構子 (或未宣告任何建構子)。若父類只有帶參建構子,子類不寫 super(...) 會編譯錯誤。

2. 顯式呼叫父類帶參建構子 (推薦做法)

class Employee {
    private String name;
    private double salary;
    public Employee(String name, double salary) {
        this.name = name; this.salary = salary;
        System.out.println("Employee(String, double)");
    }
    // 故意不提供無參建構子
}

class Trainer extends Employee {
    private String course;
    public Trainer(String name, double salary, String course) {
        super(name, salary); // 必須第一行,傳遞父類所需參數
        this.course = course;
        System.out.println("Trainer(String, double, String)");
    }
}

// new Trainer("Alice", 50000, "Java") 輸出:
// Employee(String, double)
// Trainer(String, double, String)

3. 同類別內多建構子鏈 (this() + super())

class Trainer extends Employee {
    private String course;
    private int level;

    // 主建構子
    public Trainer(String name, double salary, String course, int level) {
        super(name, salary);
        this.course = course;
        this.level = level;
    }

    // 便利建構子:預設 level=1
    public Trainer(String name, double salary, String course) {
        this(name, salary, course, 1); // 呼叫同類別主建構子
    }

    // 便利建構子:預設 course="General"
    public Trainer(String name, double salary) {
        this(name, salary, "General"); // 連鎖呼叫
    }
}

規則:this(...) 與 super(...) 二擇一,且必須是第一行。不能同時出現。

常見編譯錯誤與修正

錯誤訊息原因修正
Implicit super constructor is undefined父類無無參建構子,子類未寫 super(...)子類建構子第一行加 super(對應參數)
Constructor call must be the first statementsuper()/this() 不在第一行移至建構子第一行
Recursive constructor invocationthis() 形成循環呼叫檢查建構子鏈邏輯,確保有終點

記憶體配置時間線 (new Trainer())

  1. JVM 分配 Trainer 完整記憶體 (含繼承自 Employee 的欄位)。
  2. 執行 Trainer 建構子第一行 super(name, salary)。
  3. 執行 Employee 建構子:初始化 name, salary。
  4. 返回 Trainer 建構子:初始化 course, level。
  5. 物件完全建立,參考傳回呼叫端。

實戰建議

  1. 父類保留無參建構子 (或提供合理預設值),降低子類撰寫負擔。
  2. 子類習慣寫 super(...),即使父類有無參建構子,明確傳參更清楚意圖。
  3. 不可變物件模式:所有欄位 final,僅提供單一主建構子,便利建構子用 this() 連鎖。
  4. 建構子避免呼叫可覆寫方法 (父類建構子呼叫 overrideMe()),因子類尚未初始化,會導致 NullPointerException 或邏輯錯誤。

總結

  • 子類建構子第一行必須是 super(...) 或 this(...)。
  • 若省略,編譯器插入 super() → 要求父類有無參建構子。
  • 父類無無參建構子時,子類強制顯式 super(參數)。
  • 善用 this() 串聯便利建構子,減少重複程式碼。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved