首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 虛方法覆寫實戰:override 關鍵字、簽章一致性與動態分派範例

     編輯:關於C#

覆寫 vs. 多載 vs. 隱藏:三者關鍵差異

覆寫語法鐵律


public class Base
{
    public virtual void Foo(int x) { }           // 虛方法
    public virtual int Bar(string s) => 0;       // 虛方法有回傳值
    public abstract void AbstractMethod();       // 抽象方法隱含 virtual
}

public class Derived : Base
{
    // 正確覆寫:簽章完全一致 + override
    public override void Foo(int x) { base.Foo(x); /* 擴充 */ }
    public override int Bar(string s) => base.Bar(s) + 1;

    // 錯誤範例:
    // public override void Foo(string x) { }     // CS0508: 簽章不符
    // public new void Foo(int x) { }             // 隱藏非覆寫 (警告 CS0108)
    // public virtual override void Foo(int x) { } // CS0506: 不可加 virtual
    // private override void Foo(int x) { }       // CS0507: 不可縮小存取權
}

完整動態分派範例


public class Vehicle
{
    public int Wheels { get; set; }
    public virtual void Honk() => Console.WriteLine("Vehicle honk!");
}

public class Car : Vehicle
{
    public int Passengers { get; set; }
    public Car(int p) { Passengers = p; Wheels = 4; }
    public override void Honk() => Console.WriteLine("Beep beep!");
}

public class Truck : Vehicle
{
    public float Load { get; set; }
    public Truck(float l) { Load = l; Wheels = 6; }
    public override void Honk() => Console.WriteLine("Hooooonk!");
}

public class Test
{
    public static void Main()
    {
        Vehicle v = new Vehicle();
        Car c = new Car(5);
        Truck t = new Truck(10f);

        v.Honk(); // Vehicle honk!
        v = c; v.Honk(); // Beep beep! (實際型別 Car)
        c.Honk(); // Beep beep!
        v = t; v.Honk(); // Hooooonk! (實際型別 Truck)
        t.Honk(); // Hooooonk!
    }
}

基類呼叫時機與模式


public override void Honk()
{
    // 模式 1:前置處理 → 基類 → 後置處理
    Console.Write("Car: ");
    base.Honk(); // 呼叫基類實作
    Console.WriteLine(" (done)");

    // 模式 2:完全取代 (不呼叫 base)
    // public override void Honk() => Console.WriteLine("Beep beep!");

    // 模式 3:條件式呼叫
    // if (someCondition) base.Honk();
}

原則:若基類實作包含必要邏輯 (資源釋放、事件觸發、不變條件維護),務必呼叫 base;否則可完全取代。

抽象方法覆寫:強制實作契約


public abstract class Animal
{
    public abstract void MakeSound(); // 無實作,隱含 virtual
}

public class Dog : Animal
{
    public override void MakeSound() => Console.WriteLine("Woof!");
}
// 編譯器強制 Dog 必須 override MakeSound

常見錯誤與除錯

機制關鍵字簽章要求多型性用途
覆寫override完全一致是 (動態分派)擴充/修改基類行為
多載無 (同名不同參數)參數不同否 (靜態綁定)提供便利呼叫方式
隱藏new任意否 (靜態綁定)刻意切斷繼承鏈

設計建議

  1. 虛方法要有明確契約:XML 註解說明預期行為、base 呼叫時機、例外保證
  2. 非虛介面模式 (NVI):公開非虛方法封裝邏輯,呼叫受保護虛方法:
    
    public void Process() { Validate(); DoProcess(); Notify(); } // 非虛
    protected virtual void DoProcess() { } // 可覆寫核心
    
  3. 避免深層覆寫鏈:超過 3 層難以維護,考慮組合/策略模式替代
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
錯誤代碼原因修正
CS0506覆寫方法加上 virtual移除 virtual
CS0507覆寫方法存取層級較基類嚴格調整為相同或更寬鬆
CS0508回傳型別/參數不符修正簽章完全一致
CS0115標記 override 但基類無虛/抽象方法檢查基類簽章或移除 override
CS0239嘗試覆寫 sealed 方法移除 sealed 或放棄覆寫