super 是 Java 中訪問父類成員的核心關鍵字,涉及構造器鏈調用、方法重寫後的父方法調用、隱藏字段訪問三大核心場景。本文通過代碼實戰徹底講透 super 的語義、限制與最佳實踐。
| 用法 | 語法 | 位置限制 | 典型場景 |
|---|---|---|---|
| 調用父構造器 | super(...) | 子類構造器第一行 | 初始化父類狀態,構造器鏈 |
| 調用父方法 | super.method() | 實例方法任意處 | 擴展父邏輯、模板方法模式 |
| 訪問父字段 | super.field | 實例方法/構造器 | 子類字段隱藏父類同名字段時 |
super(...)class Animal {
protected String name;
public Animal(String name) { this.name = name; }
}
class Cat extends Animal {
private int lives;
// ✅ 正確:第一行顯式調用父構造器
public Cat(String name, int lives) {
super(name); // 必須在第一行
this.lives = lives;
}
// ✅ 正確:無參構造器隱式調用 super()
public Cat() {
super("Unknown"); // 顯式調用帶參父構造器
this.lives = 9;
}
// ❌ 錯誤:super() 不在第一行
// public Cat(String name) { this.lives = 9; super(name); } // 編譯報錯
}
關鍵規則:
super(...) 或隱式 super())。super(...)。super(...) 與 this(...) 互斥,只能二選一,且必須在第一行。super.method()class Logger {
public void log(String msg) {
System.out.println("[INFO] " + msg);
}
}
class TimestampLogger extends Logger {
@Override
public void log(String msg) {
super.log("[" + Instant.now() + "] " + msg); // 擴展而非完全替換
}
}
這是模板方法模式的基礎:父類定義骨架,子類通過 super 復用通用邏輯並注入差異化行為。
super.fieldclass Base {
protected int value = 10;
}
class Derived extends Base {
private int value = 20; // 隱藏父類 value
public void printBoth() {
System.out.println("this.value = " + this.value); // 20
System.out.println("super.value = " + super.value); // 10
}
}
最佳實踐:避免字段隱藏(易混淆),改用不同命名或封裝 getter/setter。
new Cat("Kitty", 7)
│
├─ Cat(String, int) 第一行:super("Kitty")
│ │
│ └─ Animal(String) 執行:this.name = "Kitty"
│
└─ Cat 構造器繼續:this.lives = 7
內存分配只發生一次(new Cat 觸發),構造器鏈只是在同一塊內存上依次初始化父類與子類字段,無多次分配。
static 方法屬於類,無 this/super 語境。InterfaceName.super.method() 語法。super 是連接子類與父類的橋樑:構造器鏈保證初始化順序,方法調用實現邏輯復用,字段訪問解決隱藏衝突。牢記「構造器第一行、靜態不可用、字段慎隱藏」,即可靈活駕馭繼承體系。