在同一個類中,多個方法同名但參數列表不同(個數、類型、順序任一差異),即構成重載。與返回值類型、異常聲明、修飾符無關。
public class Calculator {
public int add(int a, int b) { return a + b; }
public double add(double a, double b) { return a + b; } // 參數類型不同
public int add(int a, int b, int c) { return a + b + c; } // 參數個數不同
}
子類重新定義父類已有方法,要求:方法簽名完全一致(名稱、參數列表、返回類型兼容)。體現多態性,運行時根據對象實際類型調用。
class Animal { public void sound() { System.out.println("動物聲音"); } }
class Cat extends Animal {
@Override public void sound() { System.out.println("喵~"); }
}
| 維度 | 重載 | 重寫 |
|---|---|---|
| 發生位置 | 同一個類內部 | 父子類之間 |
| 關係類型 | 水平關係(兄弟方法) | 垂直關係(繼承鏈) |
| 參數列表 | 必須不同 | 必須相同 |
| 返回類型 | 可同可不同 | 兼容(子類返回類型可為父類返回類型子類型) |
| 訪問權限 | 無限制 | 子類權限 ≥ 父類權限 |
| 異常聲明 | 無限制 | 子類拋出異常 ⊆ 父類異常 |
| 調用綁定 | 編譯期靜態綁定 | 運行期動態綁定 |
| static/final | 可修飾 | final 禁止重寫;static 僅能隱藏不能重寫 |
protected → public ✅;public → private ❌static 子類必須 static(隱藏);父非靜態子類不可加 staticfinal 修飾的方法不可重寫class Parent { private void secret() {} }
class Child extends Parent {
void secret() {} // 這是新方法,非重寫!加 @Override 會編譯報錯
}
class Parent { static void greet() { System.out.println("Parent"); } }
class Child extends Parent {
static void greet() { System.out.println("Child"); } // 隱藏而非重寫
}
Parent p = new Child();
p.greet(); // 輸出 "Parent" — 綁定聲明類型 Parent
class Parent { String name = "Parent"; }
class Child extends Parent { String name = "Child"; }
Parent obj = new Child();
System.out.println(obj.name); // 輸出 "Parent" — 訪問聲明類型變量
System.out.println() 系列)重載是編譯期多態(靜態),重寫是運行期多態(動態)。前者解決「同一操作不同參數」的代碼復用,後者實現「同一接口不同實現」的擴展性。搞清二者邊界,是寫出健壯面向對象代碼的基石。