介面 - 定義多個類型的行為

介面包含非抽象 classstruct 必須實作之一組相關功能的定義。 介面可以定義必須具有實作的 static 方法。 介面可以定義成員的預設實作方式。 介面可能無法宣告執行個體資料,例如欄位、自動實作的屬性或類似屬性的事件。

例如,您可以藉由使用介面,在類別中包含多個來源的行為。 這項功能在 C# 中是很重要的,因為語言不支援類別的多重繼承。 此外,如果您要模擬結構繼承,則必須使用介面,因為它們實際上無法繼承自另一個結構或類別。

您要使用 interface 關鍵字來定義介面,如下列範例所示。

interface IEquatable<T>
{
    bool Equals(T obj);
}

介面的名稱必須是有效的 C# 識別碼名稱。 依慣例,介面名稱的開頭是大寫的|capital I

任何實作 IEquatable<T> 介面的類別或結構,必須包含 Equals 方法的定義,該方法符合介面指定的簽章。 如此一來,您可以倚賴實作 IEquatable<T> 的類別,以包含 Equals 方法,類別的執行個體可以使用該方法判斷它是否等於相同類別的另一個執行個體。

IEquatable<T> 的定義不提供 Equals 的實作。 不過,類別或結構可以實作多個介面,但類別只能繼承自單一類別。

如需抽象類別的詳細資訊,請參閱抽象和密封類別以及類別成員

介面可以包含執行個體方法、屬性、事件、索引子,或以上四個成員類型的組合。 介面可能包含靜態建構函式、欄位、常數或運算子。 從 C# 11 開始,非欄位的介面成員可能是 static abstract。 介面不得包含執行個體欄位、執行個體建構函式或完成項。 介面成員預設為公用,而且您可以明確地指定協助工具修飾詞,例如 publicprotectedinternalprivateprotected internalprivate protectedprivate 成員必須有預設實作。

若要實作介面成員,實作類別的對應成員必須是公用、非靜態,且具有與介面成員相同的名稱和簽章。

注意

當介面宣告靜態成員時,實作該介面的類型也可以宣告具有相同簽章的靜態成員。 那些是宣告成員的類型所區分且唯一識別的。 在類型中宣告的靜態成員不會覆寫在介面中宣告的靜態成員。

實作介面的類別或結構必須為所有宣告的成員提供實作,而不是介面提供的預設實作。 不過,如果基底類別實作介面,則衍生自基底類別的任何類別都會繼承該實作。

下列範例會示範 IEquatable<T> 介面的實作。 實作類別 Car 必須提供 Equals 方法的實作。

public class Car : IEquatable<Car>
{
    public string? Make { get; set; }
    public string? Model { get; set; }
    public string? Year { get; set; }

    // Implementation of IEquatable<T> interface
    public bool Equals(Car? car)
    {
        return (this.Make, this.Model, this.Year) ==
            (car?.Make, car?.Model, car?.Year);
    }
}

類別的屬性與索引子可以針對介面中定義的屬性或索引子定義額外的存取子。 例如,介面可能會宣告具有 get 存取子的屬性。 實作介面的類別可以宣告具有 getset 存取子的相同屬性。 不過,如果屬性或索引子使用明確的實作,則存取子必須相符。 如需明確實作的詳細資訊,請參閱明確介面實作介面屬性

介面可以繼承自一或多個介面。 衍生介面會繼承其基底介面的成員。 實作衍生介面的類別必須在衍生介面中實作所有成員,包括衍生介面基底介面的所有成員。 該類別可能會隱含地轉換成衍生介面或其任何基底介面。 類別可能透過基底類別包含介面多次,繼承或透過其他介面繼承的介面。 不過,類別只能提供介面實作一次,而且只有在類別將介面宣告為類別 (class ClassName : InterfaceName) 定義的一部分時。 如果因為您繼承實作介面的基底類別而繼承介面,則基底類別會提供介面成員的實作。 不過,衍生的類別可以實作任何虛擬介面成員,而不使用繼承的實作。 當介面宣告方法的預設實作時,實作該介面的任何類別都會繼承該實作 (您必須將類別執行個體轉換成介面類別型,才能存取介面成員上的預設實作)。

基底類別也可以使用虛擬成員來實作介面成員。 在此情況下,衍生的類別可以藉由覆寫虛擬成員來變更介面行為。 如需虛擬成員的詳細資訊,請參閱多型

介面摘要

介面具有下列屬性:

  • 在 C# 8.0 之前的版本中,介面類似只有抽象成員的抽象基底類別。 實作介面的類別或結構必須實作其所有成員。
  • 從 C# 8.0 開始,介面可能會為其部分或所有成員定義預設實作。 實作介面的類別或結構不需要實作具有預設實作的成員。 如需詳細資訊,請參閱預設介面方法
  • 介面無法直接具現化。 其成員是由實作介面的任何類別或結構實作。
  • 類別或結構可以實作多個介面。 類別可以繼承基底類別,也會實作一或多個介面。