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

Effective C# 原則 19:優先定義與實作介面,而非繼承

     編輯:關於C#

抽象類別在繼承體系中扮演「共同祖先」角色,提供預設實作;介面則定義「原子化功能合約」,任何型別皆可實作。兩者各有千秋,核心差異在於:繼承表達「is-a」關係,介面表達「behaves-like」關係。基類描述物件是什麼,介面描述物件有什麼行為。

介面:合約式設計

介面可包含方法、屬性、索引子、事件等佔位元素。實作介面的型別必須具體實作所有成員。介面不含任何實作邏輯與資料成員,純粹定義合約。優點在於:

  • 不相關型別可共同實作同一介面,極大提升程式碼重用彈性。
  • 參數與傳回值使用介面型別,能接受任意實作該介面的物件(如 IEnumerable vs CollectionBase 範例)。
  • 避免單一繼承限制,符合 .NET 環境設計。

抽象基類:共用實作與版本演進

基類可提供具體實作、資料成員、虛擬方法等。向基類新增方法,所有衍生類自動獲得;但向介面新增方法會中斷所有現有實作類別。System.Collections.CollectionBase 即採混合策略:實作 IList、ICollection、IEnumerable 介面,並提供 OnInsert 等虛擬方法供衍生類自訂行為。

實戰範例:型別安全集合

public class IntList : System.Collections.CollectionBase
{
    protected override void OnInsert(int index, object value)
    {
        try
        {
            int newValue = System.Convert.ToInt32(value);
            Console.WriteLine("Inserting {0} at position {1}", index, value);
        }
        catch (FormatException e)
        {
            throw new ArgumentException("Argument Type not an integer", "value", e);
        }
    }
    protected override void OnInsertComplete(int index, object value)
    {
        Console.WriteLine("Inserted {0} at position {1}", index, value);
    }
}

介面導向的 API 設計

回傳介面而非具體類別(如 IListSource 取代 DataSet),可:

  1. 限制呼叫端可存取的功能面,保護內部結構不被任意修改。
  2. 未來變更內部實作(改用 DataTable、DataView 或自訂型別)不破壞公開介面。
  3. 支援不相關型別共享功能(如 Employee、Customer、Vendor 皆實作 IContactInfo)。

結構體與介面:避免拆箱效能損耗

實作介面的實值型別(如 URLInfo : IComparable)在裝箱後,透過介面呼叫方法可避免拆箱左側物件,減少效能開銷。

總結

基類適合描述「相關型別的共用行為與實作」;介面適合定義「不相關型別皆可實作的原子功能塊」。善用兩者差異,能創造表達力更強、面對修改更具彈性的設計。

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