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

C# 介面深度解析:定義契約、多型實作與進階模式

     編輯:C# 入門

C# 介面深度解析:定義契約、多型實作與進階模式

在物件導向設計中,介面是定義「能做什麼」的契約,而類別負責實作「怎麼做」。介面只宣告成員(方法、屬性、事件、索引子)的簽章,不包含實作細節。這種關注點分離讓系統具備高內聚、低耦合的特性,是依賴倒置原則與多型的核心基石。

介面宣告語法

使用 interface 關鍵字定義介面,慣例以 I 開頭命名(如 IComparable、IDisposable):

public interface ITransaction {
    void ShowTransaction();      // 方法簽章
    decimal GetAmount();         // 傳回值型別
    string ReferenceCode { get; } // 唯讀屬性
    event EventHandler Processed; // 事件
}

介面成員預設為 public,不允許標示存取修飾詞(C# 8.0 前)。

實作介面:隱含與顯式實作

隱含實作

類別直接定義與介面簽章相符的 public 成員:

public class Transaction : ITransaction {
    public string ReferenceCode { get; private set; }
    public decimal Amount { get; private set; }
    public event EventHandler Processed;

    public Transaction(string code, decimal amount) {
        ReferenceCode = code;
        Amount = amount;
    }

    public void ShowTransaction() {
        Console.WriteLine($"交易:{ReferenceCode},金額:{Amount:C}");
    }

    public decimal GetAmount() => Amount;
}

顯式實作

當類別實作多個介面且成員簽章衝突,或需隱藏實作細節時,使用顯式介面實作:

public class MultiFormatExporter : IJsonExporter, IXmlExporter {
    // 顯式實作:只能透過介面型別存取
    void IJsonExporter.Export(data) { /* JSON 邏輯 */ }
    void IXmlExporter.Export(data) { /* XML 邏輯 */ }
    
    // 隱含實作:可直接透過類別實例存取
    public void ExportDefault(data) { /* 預設邏輯 */ }
}

顯式實作的成員不可標示 public,且只能透過介面型別變數呼叫:

var exporter = new MultiFormatExporter();
((IJsonExporter)exporter).Export(data); // 必須轉型
exporter.ExportDefault(data);           // 直接呼叫

介面 vs 抽象類別:如何選擇?

特性介面抽象類別
多重實作類別可實作多個介面只能繼承單一抽象類別
預設實作C# 8.0+ 支援 default 實作可包含完整實作與狀態
建構子無可有建構子
存取修飾詞成員預設 public支援完整存取控制
適用場景定義能力契約、跨層級解耦共享程式碼、定義核心實體骨架

經驗法則:優先使用介面定義契約;當需要共享邏輯或狀態時,才考慮抽象類別。

C# 8.0+ 介面新功能

預設實作

介面可提供成員的預設實作,實作類別可選擇覆寫:

public interface ILogger {
    void Log(string message);
    void LogError(string message) => Log($"[ERROR] {message}"); // 預設實作
}

靜態成員與私有方法

介面現在支援 static 成員、private 輔助方法,方便預設實作共用邏輯:

public interface ICalculator {
    static int Add(int a, int b) => a + b; // 靜態方法
    int Calculate(int x); // 實作類別必須實作
}

實戰範例:策略模式與介面

介面是策略模式的核心——定義演算法族群的共同契約:

// 策略介面
public interface IDiscountStrategy {
    decimal CalculateDiscount(decimal originalPrice);
}

// 具體策略
public class VipDiscount : IDiscountStrategy {
    public decimal CalculateDiscount(decimal price) => price * 0.85m;
}
public class SeasonalDiscount : IDiscountStrategy {
    public decimal CalculateDiscount(decimal price) => price * 0.9m;
}

// 內容類別
public class Order {
    private readonly IDiscountStrategy _strategy;
    public Order(IDiscountStrategy strategy) => _strategy = strategy;
    public decimal GetFinalPrice(decimal price) => _strategy.CalculateDiscount(price);
}

// 使用
var order = new Order(new VipDiscount());
Console.WriteLine(order.GetFinalPrice(1000)); // 850

最佳實踐

  • 介面隔離原則 (ISP):拆分臃腫介面,避免實作類別被迫實作不需要的成員。
  • 依賴倒置原則 (DIP):高層模組依賴介面,而非具體類別。
  • 命名慣例:以 I 開頭 + 形容詞/名詞(ISortable、IRepository)。
  • 保持介面精簡:單一職責,成員不超過 3-5 個為宜。
  • 文件化契約:使用 XML 註解說明前置條件、後置條件、副作用。

常見問題 FAQ

Q: 介面可以繼承介面嗎?

A: 可以。interface IExtended : IBase { } 形成介面繼承鏈,實作類別必須實作所有成員。

Q: 結構可以實作介面嗎?

A: 可以。結構支援介面實作,但不可繼承類別。這是實現值型別多型的重要方式。

Q: 什麼時候用顯式實作?

A: 1) 解決多介面同名成員衝突 2) 隱藏實作細節,強制透過介面存取 3) 實作介面成員但不想汙染類別的公用 API。

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