多態是面向對象三大特性(封裝、繼承、多態)之一,分為兩類:
日常所稱「多態」多指運行時多態。
Parent p = new Child();(向上轉型)。| 優勢 | 說明 | 例子 |
|---|---|---|
| 可替換性 | 父類型引用可指向任意子類物件 | List<Animal> 可存 Dog、Cat |
| 可擴展性 | 新增子類不修改既有代碼 | 新增 Bird 類無需改動 Animal 相關邏輯 |
| 介面性 | 父類定義契約,子類實現細節 | Shape 定義 area(),Circle/Rect 實現 |
| 靈活性 | 運行期動態決策行為 | 策略模式、插件系統 |
| 簡化性 | 統一介面處理異構物件集合 | for (Animal a : animals) a.sound(); |
當調用 obj.method(arg) 時,JVM 依以下優先級尋找方法:
this.method(arg) — 當前類實例方法super.method(arg) — 父類實例方法this.method((Super)arg) — 當前類方法,參數向上轉型super.method((Super)arg) — 父類方法,參數向上轉型口訣:本類優於父類,實際型別優於轉型型別。
class A {
public String show(D obj) { return "A and D"; }
public String show(A obj) { return "A and A"; }
}
class B extends A {
public String show(B obj) { return "B and B"; }
public String show(A obj) { return "B and A"; }
}
class C extends B {}
class D extends B {}
A a1 = new A();
A a2 = new B();
B b = new B();
C c = new C();
D d = new D();
System.out.println(a1.show(b)); // ① A and A
System.out.println(a1.show(c)); // ② A and A
System.out.println(a1.show(d)); // ③ A and D
System.out.println(a2.show(b)); // ④ B and A
System.out.println(a2.show(c)); // ⑤ B and A
System.out.println(a2.show(d)); // ⑥ A and D
System.out.println(b.show(b)); // ⑦ B and B
System.out.println(b.show(c)); // ⑧ B and B
System.out.println(b.show(d)); // ⑨ A and D
A.show(B) → 無 → super.show(B) → A 無父類 → this.show((A)b) → 找到 A.show(A) → A and A。C 父類是 B,再父類是 A,最終匹配 A.show(A) → A and A。A.show(D) → A and D。A.show(B) → 無 → super.show(B) → 無 → this.show((A)b) → 找到 A.show(A)。關鍵:實際型別 B 覆寫了 show(A),動態分派到 B.show(A) → B and A。A.show(A),動態分派到 B.show(A) → B and A。A.show(D)。實際型別 B 未覆寫 show(D),繼承自 A → A and D。B.show(B) → B and B。B.show(C) → 無 → super.show(C)(A 中無)→ this.show((B)c) → 找到 B.show(B) → B and B。B.show(D) → 無 → super.show(D) → 找到 A.show(D)。B 未覆寫 → A and D。Child c = (Child) parent; 可能拋 ClassCastException。@Override 註解,編譯期防呆。精通多態分派機制,不僅能破解面試難題,更能設計出高內聚、低耦合、易擴展的物件導向系統。