多態是面向對象三大特性(封裝、繼承、多態)中最核心的一個。簡單說:「同一操作作用於不同對象,產生不同行為」。在 Java 中,多態通過 方法重寫 配合 父類引用指向子類對象 實現。
class Parent {
private String name = "parent";
public String getName() { return this.name; }
public void doSomething(Parent obj) {
System.out.println(obj.getName()); // 動態綁定:調用實際對象的 getName()
}
public static void main(String[] args) {
Parent p = new Parent();
p.doSomething(new A()); // 輸出: class A
p.doSomething(new B()); // 輸出: class B
}
}
class A extends Parent {
private String name = "class A";
@Override public String getName() { return this.name; }
}
class B extends Parent {
private String name = "class B";
@Override public String getName() { return this.name; }
}
關鍵點:doSomething 參數類型為 Parent,但傳入 A/B 實例。JVM 在運行時根據對象實際類型 (A 或 B) 分派調用對應的 getName(),而非 Parent 的版本。這就是動態綁定。
interface Name {
String getName(); // 只有聲明,無實現
}
class A implements Name {
private String name = "class A";
public String getName() { return name; }
}
class B implements Name {
private String name = "class B";
public String getName() { return name; }
}
public class Test {
public static void main(String[] args) {
Name obj = new A(); // 接口引用指向實現類對象
System.out.println(obj.getName()); // 輸出: class A
obj = new B();
System.out.println(obj.getName()); // 輸出: class B
}
}
接口定義了「能做什麼」,實現類決定「怎麼做」。多態使代碼依賴抽象(接口)而非具體實現,符合依賴倒置原則。
Parent p = new Child(); 或 Interface i = new Impl();。| 綁定類型 | 發生時機 | 依據 | 典型例子 |
|---|---|---|---|
| 靜態綁定 (早期綁定) | 編譯期 | 引用變量聲明類型 | 私有方法、靜態方法、構造器、final 方法 |
| 動態綁定 (晚期綁定) | 運行期 | 對象實際類型 | 非私有實例方法(重寫方法) |
Parent p = new Child(); p.field 訪問的是 Parent.field(編譯期綁定),除非用 getter 方法。Parent.staticMethod() 永遠調用父類版本,子類同名方法為隱藏而非重寫。@Override 註解防止誤寫方法簽名。if-else / switch 類型判斷(策略模式)。