目錄
1. 方法重載 (Overload)
什么是方法重載?
重載的特點:
重載的示例:
重載的調用:
2. 方法重寫 (Override)
什么是方法重寫?
重寫的特點:
重寫的示例:
重寫的調用:
3. 重寫 vs 重載 對比表
4. 特殊情況和注意事項
靜態方法
私有方法
final 方法
構造方法
5. 實際應用建議
總結
在 Java 面向對象編程中,方法重寫和方法重載是兩個重要但容易混淆的概念。它們都涉及到方法的定義,但有著本質的區別。
1. 方法重載 (Overload)
什么是方法重載?
方法重載是指在同一個類中,允許存在多個同名方法,但這些方法的參數列表必須不同(參數類型、參數個數或參數順序不同)。
重載的特點:
- 發生在同一個類中
- 方法名必須相同
- 參數列表必須不同(類型、個數、順序)
- 返回類型可以相同也可以不同
- 訪問修飾符可以不同
- 可以拋出不同的異常
重載的示例:
public class Calculator {// 方法1:兩個整數相加public int add(int a, int b) {return a + b;}// 方法2:三個整數相加 - 參數個數不同public int add(int a, int b, int c) {return a + b + c;}// 方法3:兩個浮點數相加 - 參數類型不同public double add(double a, double b) {return a + b;}// 方法4:整數和浮點數相加 - 參數順序不同(雖然這里效果類似)public double add(int a, double b) {return a + b;}// 方法5:浮點數和整數相加 - 參數順序不同public double add(double a, int b) {return a + b;}
}
重載的調用:
編譯器根據方法簽名(方法名 + 參數列表)來決定調用哪個重載方法。
Calculator calc = new Calculator();
calc.add(1, 2); // 調用 add(int, int)
calc.add(1, 2, 3); // 調用 add(int, int, int)
calc.add(1.5, 2.5); // 調用 add(double, double)
2. 方法重寫 (Override)
什么是方法重寫?
方法重寫是指子類重新定義父類中已有的方法,提供特定的實現。重寫的方法必須與父類方法有相同的方法簽名和返回類型(或是其子類)。
重寫的特點:
- 發生在繼承關系的父子類之間
- 方法名必須相同
- 參數列表必須完全相同
- 返回類型必須相同或是其子類(協變返回類型)
- 訪問修飾符不能比父類更嚴格
- 不能拋出比父類方法更寬泛的檢查異常
重寫的示例:
// 父類
class Animal {public void makeSound() {System.out.println("動物發出聲音");}public Animal getAnimal() {return new Animal();}
}// 子類
class Dog extends Animal {// 重寫 makeSound 方法@Overridepublic void makeSound() {System.out.println("汪汪汪");}// 協變返回類型 - 返回 Dog 類型(Animal 的子類)@Overridepublic Dog getAnimal() {return new Dog();}
}// 另一個子類
class Cat extends Animal {@Overridepublic void makeSound() {System.out.println("喵喵喵");}
}
重寫的調用:
運行時根據對象的實際類型來決定調用哪個方法(多態的體現)。
Animal myAnimal = new Animal();
Animal myDog = new Dog();
Animal myCat = new Cat();myAnimal.makeSound(); // 輸出: 動物發出聲音
myDog.makeSound(); // 輸出: 汪汪汪 (多態)
myCat.makeSound(); // 輸出: 喵喵喵 (多態)
3. 重寫 vs 重載 對比表
特性 | 方法重載 (Overload) | 方法重寫 (Override) |
發生位置 | 同一個類中 | 繼承關系的父子類之間 |
方法名 | 必須相同 | 必須相同 |
參數列表 | 必須不同 | 必須完全相同 |
返回類型 | 可以不同 | 必須相同或是其子類 |
訪問修飾符 | 可以不同 | 不能比父類更嚴格 |
異常拋出 | 可以不同 | 不能拋出更寬泛的檢查異常 |
調用時機 | 編譯時決定 | 運行時決定(多態) |
目的 | 提高方法靈活性 | 實現多態,定制子類行為 |
注解 | 可選使用 | 建議使用 |
4. 特殊情況和注意事項
靜態方法
靜態方法可以被"重載",但不能被"重寫"。如果子類定義了與父類相同的靜態方法,這稱為方法隱藏(Method Hiding),不是重寫。
class Parent {static void staticMethod() {System.out.println("Parent static method");}
}class Child extends Parent {static void staticMethod() { // 這是隱藏,不是重寫System.out.println("Child static method");}
}
私有方法
私有方法不能被重寫,因為它們在子類中不可見。私有方法可以被重載。
final 方法
final 方法不能被重寫,但可以被重載。
構造方法
構造方法可以被重載(在同一個類中),但不能被重寫(因為構造方法不能繼承)。
5. 實際應用建議
- 使用 @Override 注解:在重寫方法時加上
@Override
注解,讓編譯器幫助檢查是否正確重寫 - 遵守里氏替換原則:子類重寫的方法不應該改變父類方法的預期行為
- 謹慎重寫:不要隨意重寫核心方法,特別是
equals()
,hashCode()
,toString()
等方法 - 文檔注釋:為重寫方法添加適當的文檔注釋,說明與父類方法的區別
總結
方法重載和重寫是 Java 多態性的兩種不同表現形式:
- 重載是編譯時多態,通過不同的參數列表提供方法的不同版本
- 重寫是運行時多態,通過子類定制父類行為來實現真正的多態
理解它們的區別對于編寫良好的面向對象代碼至關重要。記住這個簡單的口訣:重載同類不同參,重寫異類同參不同實現。