首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java 多態機制深度解析:父類引用指向子類物件時的方法調用規則

     編輯:程式設計綜合問答

程式碼場景

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
    }
}

核心問題解答

1. 為什麼寫成 `Auto auto = new Car()`?

這是多態的體現:父類引用指向子類物件。好處是:

  • 提高程式碼靈活性,統一介面處理不同子類。
  • 便於擴展,新增子類無需修改使用端代碼。
  • 符合「面向介面編程」原則。

當然也可以寫 `Car auto = new Car()`,但會失去多態優勢。

2. 為什麼 `auto.fun()` 輸出 "a poor engine"?

關鍵在於 Car.fun() 的實現:

public void fun() { super.engine(); } // 顯式呼叫父類方法
  • auto.fun() → 執行 Car.fun()(動態繫結)
  • Car.fun() 內部呼叫 super.engine() → 靜態繫結到 Auto.engine()
  • 因此輸出父類的 "a poor engine"

3. 為什麼 `auto.engine()` 輸出 "a nice engine"?

  • auto.engine() → 動態繫結到 Car.engine()(方法覆寫)
  • 輸出子類覆寫後的 "a nice engine"

多態調用鐵律

調用方式繫結時機執行版本
實例方法(非 private/static/final)執行期(動態繫結)子類覆寫版本
super.method()編譯期(靜態繫結)父類版本
private/static/final 方法編譯期(靜態繫結)宣告類版本

記憶口訣

「引用型態決定能調什麼,物件型態決定調誰的,super 強制指定調父的。」

進階延伸

若 Car 未覆寫 engine(),則 auto.engine() 會調用父類版本。若 Auto 宣告為 abstract 並將 engine() 設為抽象方法,則強制子類實現,設計更嚴謹。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved