this 是當前物件的引用,型別為執行時期的實際類別(而非宣告所在類別)。this 可參與 instanceof、作為參數傳遞、呼叫方法/存取欄位。super 不是引用,無法獨立使用,僅用於呼叫父類建構子或存取被遮蔽的父類成員。public static void main(String[] args) {
new SubT3().func(); // 關鍵:建立 SubT3 實例,呼叫繼承自 SuperT3 的 func()
SuperT3 s = new SuperT3();
System.out.println(s instanceof SubT3); // false:s 是 SuperT3 實例,非 SubT3
}
protected void func() {
System.out.println(this.name); // 輸出 "Jack"
System.out.println(this instanceof SuperT3); // true
System.out.println(this instanceof SubT3); // true!關鍵點
}
this 指向的是 new SubT3() 建立的實例。name 是成員變數,不參與多態。編譯器根據引用型別(此處 this 在 SuperT3 方法中,靜態型別為 SuperT3)解析為 SuperT3.name。instanceof 檢查執行時期實際物件型別,物件確實是 SubT3 實例。SubT3 實例記憶體佈局: +------------------+ | SuperT3 部分 | <-- this (SuperT3 型別視圖) | name = "Jack" | | +------------------+ | | SubT3 部分 | +-- this (SubT3 型別視圖,同一起始位址) | name = "Peter" | | +------------------+
單一物件包含父類與子類的所有實例欄位。父類欄位 name 與子類欄位 name 共存,位於不同偏移量。
設計哲學:若子類同名欄位能覆蓋父類欄位,父類方法存取 this.field 時將看到子類值,導致父類邏輯錯亂(如父類陣列存 0,1,2 卻被子類同名陣列 3,4,5 取代)。
解決方案:
private,提供 getter/setter 方法(方法可多態)。| 用法 | 範例 | 說明 |
|---|---|---|
| 呼叫父類建構子 | super(id, name); | 必須在子類建構子第一行 |
| 存取被遮蔽的父類欄位 | super.name | 繞過子類同名欄位,直接存取父類欄位 |
| 呼叫被覆寫的父類方法 | super.func() | 明確調用父類實現,常用於擴充而非完全取代 |
super 不能:單獨賦值給變數、傳遞給方法、參與 instanceof。
錯。this 型別是實際物件的類別。父類方法中 this.getClass() == SubT3.class。
錯。欄位存取在編譯期根據引用靜態型別解析。((SuperT3)sub).name 和 ((SubT3)sub).name 可分別存取父/子類同名欄位。
方法呼叫 this.method() 會動態派發到實際類別的實現。欄位存取、靜態方法、私有方法、建構子均不參與多態。
private + getter/setter,避免遮蔽混淆。this 是指向當前執行物件的引用,型別為實際類別。成員變數不支援多態,編譯期根據引用靜態型別綁定。super 不是引用,僅用於存取父類被遮蔽/覆寫成員。掌握靜態型別 vs 動態型別、欄位 vs 方法、編譯期綁定 vs 執行期派發三組核心對比,即可徹底理解 Java 物件模型運作機制。