同一類中,方法名相同,參數列表不同(類型、個數、順序),返回類型可同可不同,不能以返回類型區分重載。
public class Dog {
public void bark() { System.out.println("no barking!"); }
public void bark(String sound) { System.out.println(sound); }
public void bark(int times, String sound) { /* ... */ }
}
子類對父類非私有方法進行重新實現,方法簽名(名、參數、返回類型)完全一致。
final。private(子類不可見,屬新方法)。static(屬隱藏而非重寫)。class Base { void test(int i) { System.out.print(i); } }
class Sub extends Base {
@Override void test(int i) { System.out.println(++i); }
}
public class Demo {
public static void main(String[] args) {
Base b = new Sub();
b.test(0); // 輸出 1(動態綁定調用 Sub.test)
b.test((byte)0); // 輸出 0(Sub 未重寫 byte 版本,調用 Base.test)
}
}
關鍵:引用類型決定調用哪個方法簽名(編譯期),對象實際類型決定執行哪個實現(運行期)。
| 維度 | 重載 | 重寫 |
|---|---|---|
| 發生位置 | 同一類 | 父子類 |
| 方法名 | 相同 | 相同 |
| 參數列表 | 必須不同 | 必須相同 |
| 返回類型 | 可同可不同 | 兼容(協變) |
| 綁定時機 | 編譯期(靜態) | 運行期(動態) |
| 多態類型 | 編譯時多態 | 運行時多態 |
| 訪問權限 | 無限制 | 子類 ≥ 父類 |
| 拋出異常 | 無限制 | 子類 ≤ 父類 |
System.out.println 系列)。@Override 註解防止低級錯誤。