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

C# 實作繼承深度解析:虛擬方法、覆寫、密封與設計契約

     編輯:C# 入門

實作繼承核心概念

**實作繼承** 讓衍生類別繼承基類別的**欄位、屬性、方法實作**。衍生類別即擁有基類別的所有非私有成員,並可:
1. **繼承原樣使用** (不修改)。
2. **覆寫** — 以 virtual/override 替換實作。
3. **隱藏** — 以 new 定義同名成員 (非多型)。
4. **擴充** — 新增衍生類別專屬成員。

基類別設計:虛擬成員與密封


public class Animal {
    public string Name { get; set; }
    public int Age { get; set; }

    // 虛擬方法:允許衍生類覆寫,提供預設實作
    public virtual void MakeSound() {
        Console.WriteLine($"{Name} makes a generic sound.");
    }

    // 虛擬屬性
    public virtual string Habitat => "Unknown";

    // 密封虛擬方法:允許覆寫一次,但禁止進一步覆寫
    public virtual void Sleep() {
        Console.WriteLine($"{Name} sleeps.");
    }

    // 非虛擬方法:不可覆寫,僅能隱藏
    public void Breathe() {
        Console.WriteLine($"{Name} breathes.");
    }

    // 密封類別:完全禁止繼承
    // public sealed class SealedAnimal { ... }
}

衍生類別:覆寫與隱藏


public class Dog : Animal {
    public string Breed { get; set; }

    // 覆寫虛擬方法:多型生效
    public override void MakeSound() {
        Console.WriteLine($"{Name} barks: Woof!");
        // base.MakeSound(); // 可選:呼叫基類實作
    }

    // 覆寫虛擬屬性
    public override string Habitat => "Domestic / Worldwide";

    // 覆寫密封虛擬方法 (若基類 Sleep 為 virtual 非 sealed)
    // public sealed override void Sleep() { ... } // 密封此路徑

    // 隱藏非虛擬成員:非多型,僅靜態繫結
    public new void Breathe() {
        Console.WriteLine($"{Name} breathes heavily (dog).");
    }

    // 衍生類專屬方法
    public void Fetch() => Console.WriteLine($"{Name} fetches the ball!");
}

多型行為實證


Animal a = new Dog { Name = "Buddy", Breed = "Golden Retriever" };
a.MakeSound();  // ✅ 輸出: "Buddy barks: Woof!" (虛擬調度)
a.Sleep();      // ✅ 輸出: "Buddy sleeps." (繼承基類實作)
a.Breathe();    // ⚠️ 輸出: "Buddy breathes." (靜態繫結至 Animal.Breathe)

Dog d = (Dog)a;
d.Breathe();    // ✅ 輸出: "Buddy breathes heavily (dog)." (靜態繫結至 Dog.Breathe)
d.Fetch();      // ✅ 衍生類專屬

關鍵字語意總覽

關鍵字位置效果
virtual基類方法/屬性/索引子/事件宣告可被覆寫,提供預設實作
override衍生類成員替換虛擬成員實作,**多型調度**
sealed類別 / override 方法類別:禁止繼承;方法:禁止進一步覆寫
abstract類別 / 成員類別:不可實例化;成員:無實作,**強制**衍生類覆寫 (隱含 virtual)
new衍生類成員隱藏基類同名成員,**無多型**,編譯器警告 CS0108
base衍生類內部存取基類實作 (base.Method()、base.Property)

設計原則:里氏替換原則 (LSP) 與組合優於繼承

  1. is-a 關係:Dog is an Animal ✅;Square is a Rectangle ❌ (寬高獨立性破壞)。
  2. 契約不變:覆寫方法**前置條件不強於基類、後置條件不弱於基類**。
  3. 優先組合:class Dog { IAnimalBehavior Behavior; } 而非深層繼承樹。策略模式、裝飾模式替代繼承爆炸。
  4. 封裝易變點:將「叫聲」、「移動方式」抽為介面/策略,而非在繼承層級硬編碼。

進階:抽象基類與模板方法模式


public abstract class DataProcessor {
    // 模板方法:定義演算法骨架
    public void Process() {
        ReadData();
        var data = TransformData(); // 抽象步驟
        WriteData(data);
    }

    protected abstract string TransformData(); // 強制實作
    protected virtual void ReadData() { Console.WriteLine("Reading..."); } // 可選覆寫
    protected virtual void WriteData(string data) { Console.WriteLine($"Writing: {data}"); }
}

public class CsvProcessor : DataProcessor {
    protected override string TransformData() => "CSV_DATA";
}

public class JsonProcessor : DataProcessor {
    protected override string TransformData() => "JSON_DATA";
    protected override void WriteData(string data) => Console.WriteLine($"JSON Output: {data}");
}

結語

實作繼承是強大但危險的工具。**virtual/override** 啟用多型、**sealed** 限制擴充、**new** 僅為隱藏兼容、**abstract** 強制契約。遵循 LSP、優先組合、封裝易變點,將繼承深度控制在 2-3 層,才能發揮其代碼重用優勢而不陷入剛性、脆弱的類別階層。

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