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

[你必須知道的.NET] 第二回:對抽象編程——介面與抽象類的抉擇指南

     編輯:關於.NET

介面與抽象類是物件導向設計中「面向抽象編程」的兩大支柱。雖然兩者都無法直接實例化、都定義契約供衍生類實作,但其適用場景、能力邊界與設計意圖截然不同。本文將從概念、異同、14 條實戰法則、經典範例與社群觀點五個維度,幫你建立清晰的決策框架。

1. 核心定義對比

特性介面抽象類別
繼承模式多重實作 (: 介面1, 介面2)單一繼承 (: 基類)
成員類型僅簽名:方法、屬性、索引子、事件可含欄位、已實作方法、建構函式、抽象成員
存取修飾詞預設 public,不可標記可使用 public/protected/internal/private
靜態成員C# 不允許(CLR 允許)允許
適用類型值類型 (struct) 與引用類型皆可僅限引用類型
設計意圖CAN-DO 行為契約(如 IComparable)IS-A 型別階層,共享實作與狀態
版本演進新增成員會破壞所有實作類別可在基類新增實作,不強制衍生類修改
回呼支援支援(介面型別參數)不支援(單一繼承限制)

2. 14 條實戰決策法則 (T14)

  1. 核心原則:面向介面編程,依賴抽象而非具體
  2. 關係密切(IS-A):優先抽象類(如 Animal → Dog/Cat)
  3. 關係疏離(CAN-DO):優先介面(如 IDisposable、IComparable)
  4. 介面單一職責:FCL 中 IEnumerable、IEquatable 等皆僅一核心方法
  5. 介面不變原則:擴充請新增介面 (IInterface2),勿修改既有介面
  6. 命名慣例:介面冠 I 前綴(如 IRepository)
  7. 預期版本變更:抽象類更易維護版本演進
  8. 需提供預設實作:抽象類
  9. 需定義欄位/狀態:抽象類
  10. 值類型需實作:只能用介面(struct 不能繼承類別)
  11. 非抽象衍生類:必須實作所有抽象成員
  12. 抽象類不可 sealed/new:因不可實例化
  13. 抽象成員不可 static/virtual:語意衝突
  14. FCL 參考:集合用介面 (System.Collections),資料流用抽象類 (System.IO.Stream)

3. 經典實作範例

// 抽象類:共享狀態與部分實作
public abstract class Animal {
    protected string _name;
    public abstract string Name { get; }
    public abstract void Show();
    public void MakeVoice() => Console.WriteLine("All animals can make voice!");
}

// 介面:定義行為契約
public interface IAction { void Move(); }

// 實作雙重契約
public class Duck : Animal, IAction { ... }
public class Dog  : Animal, IAction { ... }

// 客戶端:面向抽象程式設計
Animal duck = new Duck("Duck");
duck.MakeVoice(); duck.Show();
IAction dogAction = new Dog("Big Dog");
dogAction.Move();

4. 社群與 MSDN 觀點彙整

  • dunai:抽象類 = 提取公因式;介面 = 將不相關類別「雜湊」成群體
  • Artech:代碼重用與擴充性優先抽象類,介面優勢不可忽視
  • shenfx:差異大找共性用介面;共性大找差異用抽象基類
  • MSDN:多版本→抽象類;廣泛異構物件→介面;小功能塊→介面;大功能單元/共享實作→抽象類

5. 結語

介面與抽象類無優劣之分,只有適用與否。掌握 T14 法則、閱讀 FCL 設計、大量實作練習,才能在架構決策中游刃有餘。記住:面向抽象編程,才是設計模式落地的靈魂。

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