方法重寫是 Java 多態的核心體現。本文系統講解重寫定義、@Override 註解作用、五大硬性規則(參數列表、返回類型、訪問權限、拋出異常、final/static 限制)、代碼實戰與常見誤區,助你精準掌握重寫機制。
子類繼承父類非私有方法後,保持方法簽名完全一致(方法名、參數列表、返回類型),重新實現方法體,稱為重寫。運行時根據對象實際類型動態分發(動態綁定)。
public class Person {
public void eat() {
System.out.println("父類 Person eat");
}
}
public class Student extends Person {
@Override
public void eat() {
System.out.println("子類 Student eat");
}
public static void main(String[] args) {
Student s = new Student();
s.eat(); // 輸出:子類 Student eat
}
}
調用父類方法:子類中用 super.eat() 顯式調用。
| 規則 | 要求 | 違反後果 |
|---|---|---|
| 1. 參數列表 | 必須完全相同(個數、類型、順序) | 變為重載 |
| 2. 返回類型 | JDK 5 前必須相同;JDK 5+ 支持協變返回類型(子類返回類型為父類返回類型的子類) | 編譯錯誤 |
| 3. 訪問權限 | 子類權限 ≥ 父類權限(public > protected > default > private) | 編譯錯誤 |
| 4. 拋出異常 | 子類異常 ≤ 父類異常(範圍更小、更少、或不拋) | 編譯錯誤 |
| 5. 非 final/static | 父類方法不能是 final(不可重寫)或 static(屬於類,非多態) | 編譯錯誤 / 隱藏而非重寫 |
// 父類
public void doSomething(int a, String b) {}
// 子類 - 錯誤:參數類型不同 -> 重載
public void doSomething(String a, int b) {}
class Animal {}
class Cat extends Animal {}
class Parent {
public Animal get() { return new Animal(); }
}
class Child extends Parent {
@Override
public Cat get() { return new Cat(); } // 合法:Cat 是 Animal 子類
}
class Parent {
protected void method() {} // protected
}
class Child extends Parent {
@Override
public void method() {} // 合法:public > protected
// private void method() {} // 錯誤:private < protected
}
class Parent {
void method() throws IOException, SQLException {}
}
class Child extends Parent {
@Override
void method() throws FileNotFoundException {} // 合法:FileNotFoundException 繼承 IOException
// void method() throws Exception {} // 錯誤:Exception 範圍更大
}
final:編譯期綁定,禁止重寫。static:屬於類,不屬於實例。子類定義同名 static 方法叫方法隱藏,非多態。private:不可繼承,自然不可重寫(子類同名方法是新方法)。| 維度 | 重寫 | 重載 |
|---|---|---|
| 發生位置 | 父子類 | 同一類 |
| 方法名 | 相同 | 相同 |
| 參數列表 | 相同 | 不同 |
| 返回類型 | 相同/協變 | 可不同 |
| 多態性 | 運行時動態綁定 | 編譯時靜態綁定 |
方法重寫是實現多態、模板方法模式、策略模式的基石。牢記「參數同、返回兼、權限大、異常小、非靜止」,善用 @Override,寫出正確且可擴展的面向對象代碼。