首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 入門教學 (14):方法多載 vs 方法覆寫 - 核心差異與實戰陷阱

     編輯:Java 相關知識

一張表看懂本質差異

維度方法多載方法覆寫
英文術語OverloadingOverriding
發生範圍同一個類別內父子類別之間
方法名稱相同相同
參數列表必須不同 (型別/個數/順序)必須相同
回傳型別可不同必須相同或為協變型別 (子類型)
存取修飾詞無限制不能比父類更嚴格 (public → protected ❌)
拋出異常無限制不能拋出比父類更廣的檢查型異常
綁定時機編譯期靜態綁定執行期動態綁定 (多型)
目的方便呼叫者,同名處理不同參數子類特化父類行為,實現多型

方法多載:Math.abs() 經典範例

public class Math {
    public static int abs(int a) { return a < 0 ? -a : a; }
    public static long abs(long a) { return a < 0 ? -a : a; }
    public static float abs(float a) { return a < 0 ? -a : a; }
    public static double abs(double a) { return a < 0 ? -a : a; }
}

// 呼叫端
int i = Math.abs(-5);      // 呼叫 abs(int)
long l = Math.abs(-5L);    // 呼叫 abs(long)
double d = Math.abs(-5.0); // 呼叫 abs(double)

編譯器根據實參型別決定呼叫哪個 abs,零耗能、極易閱讀。

方法覆寫:薪資計算多型範例

class Employee {
    protected double salary;
    public void setSalary(double base, double rate) {
        this.salary = base * (1 + rate); // 一般調薪公式
    }
}

class Sales extends Employee {
    @Override
    public void setSalary(double base, double rate) {
        this.salary = base * (1 + 2 * rate); // 業務提成雙倍
    }
}

// 多型呼叫
Employee e = new Sales();
e.setSalary(10000, 0.1); // 實際執行 Sales.setSalary,薪資 = 12000

@Override 註解可在編譯期檢查簽名是否真正匹配父類,強烈建議永遠加上。

新手最易混淆的三個迷思

  1. 「參數名稱不同算多載」 → 錯。參數名稱不影響簽名,只有型別、個數、順序不同才是多載。
  2. 「覆寫可以改回傳型別」 → 只能協變 (父 Number → 子 Integer),不能任意改。
  3. 「私有方法也能覆寫」 → 錯。private 方法不可見,子類同名方法只是新方法,非覆寫。

覆寫的三大鐵律 (必背)

  1. 同名、同參、同回傳 (或協變)。
  2. 存取權限 ≥ 父類 (public > protected > default > private)。
  3. 拋出異常 ≤ 父類 (子類可拋更少、更具體的異常)。

實戰練習:判斷多載還是覆寫

class Base {
    public void foo(int a) {}
    protected void bar(String s) {}
    void baz() {} // package-private
}

class Derived extends Base {
    public void foo(long a) {}        // 1. 多載 (參數型別不同)
    public void foo(int a) {}         // 2. 覆寫 (完全相同)
    protected void bar(String s) {}   // 3. 覆寫 (權限相同)
    public void bar(String s) {}      // 4. 覆寫 (權限放寬 protected→public ✓)
    // void baz() {}                   // 5. 編譯錯誤:權限縮小 (default→private ❌)
    public void baz() {}              // 6. 覆寫 (權限放寬 default→public ✓)
}

總結

  • 多載 = 同類別、同名、不同參數,靜態綁定,方便呼叫。
  • 覆寫 = 父子類、同名、同參數,動態綁定,實現多型。
  • 永遠加 @Override,編譯器幫你擋住簽名不匹配的低級錯誤。
  • 覆寫遵守「權限不縮小、異常不擴大、回傳協變」三鐵律。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved