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

C# override vs new:重寫與隱藏的語義區別與適用場景

     編輯:程式設計綜合問答

核心區別速查表

關鍵字語義多態行為基類要求典型場景
override重寫虛方法/抽象方法✅ 基類引用指向派生對象時調用派生實現基類標註 virtual/abstract/override擴展/修改基類行為,保持契約
new隱藏基類同名成員❌ 基類引用調用基類實現,派生引用調用派生實現無要求,基類可無虛標記被迫實現同名接口、避免命名衝突

代碼演示:多態差異


public class Base {
    public virtual void VirtualMethod() { Console.WriteLine("Base.Virtual"); }
    public void NormalMethod() { Console.WriteLine("Base.Normal"); }
}

public class Derived : Base {
    public override void VirtualMethod() { Console.WriteLine("Derived.Virtual"); }  // 重寫
    public new void NormalMethod() { Console.WriteLine("Derived.Normal"); }          // 隱藏
}

// 測試
Base b = new Derived();
b.VirtualMethod();  // 輸出: Derived.Virtual  (多態生效)
b.NormalMethod();   // 輸出: Base.Normal      (靜態綁定)

Derived d = new Derived();
d.NormalMethod();   // 輸出: Derived.Normal   (派生類型調用隱藏版)

何時使用 new?

  1. 實現接口強制同名:派生類需實現 IInterface.Method(),但基類已有同名非虛方法,無法 override,只能 new 隔離
  2. 第三方庫無虛方法:無法修改基類源碼添加 virtual,需在派生類提供新實現
  3. 語義明確不相關:同名純屬巧合,業務邏輯無繼承關係,用 new 表達「這是新成員」

最佳實踐與編譯器警告

  • 默認首選 override,設計基類時主動標記 virtual 開放擴展點
  • 使用 new 時**必須**加上關鍵字,否則編譯器發出 CS0108 警告:「'Derived.Method()' 隱藏繼承成員,若有意請用 new」
  • 避免在公共 API 中濫用 new,導致多態行為違反直覺,增加維護認知負擔
  • 若基類方法標記 sealed override,派生類不可再 override,只能 new 隔離

設計原則

「override 表達『我是同一契約的不同實現』,new 表達『我只是碰巧同名,實則另一回事』。」

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