public class Auto {
public void engine() { System.out.println("a poor engine"); }
public void fun() { System.out.println("Driving fun"); }
}
public class Car extends Auto {
public void engine() { System.out.println("a nice engine"); }
public void fun() { super.engine(); }
public static void main(String[] args) {
Auto auto = new Car();
auto.fun(); // 輸出: a poor engine
auto.engine(); // 輸出: a nice engine
}
}
這是多態的體現:父類引用指向子類物件。好處是:
當然也可以寫 `Car auto = new Car()`,但會失去多態優勢。
關鍵在於 Car.fun() 的實現:
public void fun() { super.engine(); } // 顯式呼叫父類方法
auto.fun() → 執行 Car.fun()(動態繫結)Car.fun() 內部呼叫 super.engine() → 靜態繫結到 Auto.engine()auto.engine() → 動態繫結到 Car.engine()(方法覆寫)| 調用方式 | 繫結時機 | 執行版本 |
|---|---|---|
| 實例方法(非 private/static/final) | 執行期(動態繫結) | 子類覆寫版本 |
| super.method() | 編譯期(靜態繫結) | 父類版本 |
| private/static/final 方法 | 編譯期(靜態繫結) | 宣告類版本 |
「引用型態決定能調什麼,物件型態決定調誰的,super 強制指定調父的。」
若 Car 未覆寫 engine(),則 auto.engine() 會調用父類版本。若 Auto 宣告為 abstract 並將 engine() 設為抽象方法,則強制子類實現,設計更嚴謹。