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

Java 方法重寫 vs 重載:規則對比、多態本質與面試高頻考點

     編輯:Java 綜合教學

Java 方法重寫 vs 重載:規則對比、多態本質與面試高頻考點

重寫 發生在父子類之間,體現運行時多態(動態分派);重載 發生在同一類內(或父子類),體現編譯時多態(靜態分派)。

核心規則對比表

維度重寫重載
發生位置子類重寫父類方法同一類中(或子類對父類方法重載)
方法名必須相同必須相同
參數列表必須完全相同必須不同(類型/個數/順序)
返回類型必須相同或协变返回类型(Java 5+ 子類型)可以相同,可以不同
訪問修飾符不能更低(public > protected > default > private)可任意修改
拋出異常不能拋出新的或更寬的檢查異常可拋出任意異常
靜態方法不能重寫(隱藏)可重載
final 方法不能重寫可重載
private 方法不能重寫(不可見)可重載(同類內)
構造方法不能重寫可重載(同類多構造器)
多態類型運行時多態(動態綁定)編譯時多態(靜態綁定)

代碼示例

重寫

class Animal {
    public void move() { System.out.println("動物移動"); }
    public Animal getSelf() { return this; }
}
class Dog extends Animal {
    @Override
    public void move() { System.out.println("狗跑"); } // 參數、返回類型相同
    @Override
    public Dog getSelf() { return this; } // 協變返回類型
}

重載

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; } // 參數個數不同
    public int add(int a, int b, int c, int d) { return a + b + c + d; }
}

深度解析

1. 協變返回類型

子類重寫方法返回類型可以是父類返回類型的子類。實現「工廠方法」鏈式調用、Builder 模式鏈式返回 this。

2. 靜態方法隱藏而非重寫

class Parent { static void foo() { System.out.println("Parent"); } }
class Child extends Parent { static void foo() { System.out.println("Child"); } }
Parent p = new Child();
p.foo(); // 輸出 "Parent" —— 編譯期綁定 Parent.foo(),無動態分派

3. 私有方法不可重寫

子類定義同名私有方法屬於新方法,與父類無關。若父類私有方法被子類調用(父類公共方法內部調用),仍執行父類版本。

4. 異常規則本質

重寫方法拋出異常必須是父類方法拋出異常的子類(或不拋出),保證調用端 catch (ParentException) 能捕獲所有子類實現拋出的異常,維護契約兼容性。

面試高頻陷阱題

  1. 構造器能否重寫? 不能。構造器不屬於成員方法,無法繼承,子類必須調用 super() 初始化父類部分。
  2. 靜態方法能否重寫? 不能,稱為方法隱藏。引用類型決定調用哪個版本。
  3. 返回類型不同能否重載? 能,但僅靠返回類型不同無法重載(編譯器無法根據調用上下文區分)。
  4. 子類能否重載父類方法? 能。子類定義同名不同參數方法,構成重載(對父類方法不可見時)。
  5. 重寫方法能否用 @Override 註解? 必須加,編譯器驗證確實重寫,防止拼寫錯誤導致變為重載。

多態本質總結

  • 重寫:JVM 根據對象實際類型在虛方法表中查找方法入口(invokevirtual 指令),實現「同一接口,不同實現」。
  • 重載:編譯器根據靜態類型和參數列表解析方法符號引用(invokestatic/invokespecial/invokevirtual),生成字節碼時已確定調用目標。

清晰區分「重寫=繼承+多態」與「重載=同名+不同參數」,是掌握 Java 面向對象核心機制、通過面試、寫出正確代碼的基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved