介面會定義合約。 任何 class實作該合約的 、 record、 或 struct 必須提供介面中定義成員的實作。
介面可以定義成員的 預設實作 。 它也可以定義 static 成員,以提供一般功能的單一實作。
介面可以定義 static abstract 或 成員 static virtual ,宣告實作型別必須提供宣告的成員。 通常 static virtual 方法會宣告實作必須定義一組 多載運算子。
在下列範例中,類別 ImplementationClass 必須實作名為 SampleMethod 的方法,該方法沒有參數並會傳回 void。
interface ISampleInterface
{
void SampleMethod();
}
class ImplementationClass : ISampleInterface
{
// Explicit interface member implementation:
void ISampleInterface.SampleMethod()
{
// Method implementation.
}
static void Main()
{
// Declare an interface instance.
ISampleInterface obj = new ImplementationClass();
// Call the member.
obj.SampleMethod();
}
}
如需詳細資訊與範例,請參閱介面。
存取修飾詞
介面可以是命名空間或類別的成員。 頂層介面 (在命名空間中宣告,但在另一種型別內不會建立巢狀) 可以宣告為 public 或 internal。 預設值為 internal。 巢狀介面宣告若在其他類型中宣告,則可用任何存取修飾符宣告。
沒有實作的介面成員(抽象成員)是隱含public且不能有其他存取修飾子的。 如果未指定存取修飾詞,則預設會是具有預設實作的介面成員,private但可以使用任何存取修飾詞 (public、 、 privateprotected或 internal) 來宣告。
介面成員
介面宣告可以包含下列成員:
預設介面成員
成員宣告通常不包含內文,不過,介面成員可以宣告內文。 介面中的成員主體預設實作。 具有主體的成員允許介面為未提供覆寫實作的類別和結構提供「預設」實作。
重要
新增預設介面成員會強制實作介面的任何 ref struct,以新增該成員的明確宣告。
靜態抽象和虛擬成員
介面可宣告static abstractstatic virtual所有成員類型(欄位除外)的成員。 介面可以宣告實作型別必須定義運算子或其他靜態成員。 此功能可讓泛型演算法指定類似數位的行為。 您可以在 .NET 執行階段的數字型別中看到範例,例如 System.Numerics.INumber<TSelf>。 這些介面定義了由多種數值類型實作的常見數學運算子。 編譯器必須在編譯時間解析呼叫 static virtual 和 static abstract 方法。 介面中宣告的 static virtual 和 static abstract 方法沒有類似在類別宣告中執行階段分派機制分派的virtual 或 abstract方法。 而編譯器會使用編譯時間可用的型別資訊。 因此,static virtual 方法幾乎均在泛型介面中完全宣告。 此外,大多數宣告 static virtual 或 static abstract 方法的介面都會宣告其中一個型別參數必須實作宣告的介面。 例如,INumber<T> 介面宣告 T 必須實作 INumber<T>。 編譯器會使用型別引數解析對介面宣告中所宣告的方法和運算子的呼叫。 例如,int型別實作 INumber<int>。 當型別參數 T 代表型別引數 int 時,會叫用在 static宣告的 int 成員。 或當 double 是型別引數時,會叫用在 static 型別上宣告的 double 成員。
重要
使用運算式的編譯時間型別解析介面中宣告的 static abstract 和 static virtual 方法的方法分派。 若表達式的執行時型別來自不同的編譯時型別,則會呼叫該基底(編譯時)型態上的靜態方法。
您可以使用介面中靜態抽象成員的教學課程嘗試這項功能。
介面繼承
介面不能包含執行個體狀態。 雖然現在可使用靜態欄位,但介面中不允許使用執行個體欄位。 介面中不支援執行個體自動屬性,因為其會隱含地宣告隱藏欄位。 此規則對屬性宣告有些微影響。 在介面宣告中,下列程式代碼不會在 或 class中struct宣告自動實作的屬性。 相反,它會宣告未預設實作的屬性,但必須在實作介面的任何型別中實作:
public interface INamed
{
public string Name {get; set;}
}
介面可以繼承一或多個基底介面。 當一個介面繼承自另一個介面時,實作衍生介面的類型必須實作基介面中的所有成員,並包含衍生介面中宣告的成員,如下程式碼所示:
public interface I1
{
void M1();
}
public interface I2 : I1
{
void M2();
}
public class C : I2
{
// implements I1.M1
public void M1() { }
// implements I2.M2
public void M2() { }
}
當介面 覆寫基底介面中實作的 方法時,它必須使用明確介面實作語法。
當基底類型清單包含基底類別和介面時,基底類別一定會排在清單的第一個。
實作介面的類別能夠明確實作該介面的成員。 明確實作的成員不能經由類別執行個體存取,只能經由介面的執行個體來存取。 此外,預設介面成員只能透過介面的執行個體存取。
如需明確介面實作的詳細資訊,請參閱明確介面實作。
介面實作範例
下列範例示範介面實作。 在此範例中,介面包含屬性宣告,而類別包含實作。 實作 IPoint 的任何類別執行個體都有整數屬性 x 和 y。
interface IPoint
{
// Property signatures:
int X { get; set; }
int Y { get; set; }
double Distance { get; }
}
class Point : IPoint
{
// Constructor:
public Point(int x, int y)
{
X = x;
Y = y;
}
// Property implementation:
public int X { get; set; }
public int Y { get; set; }
// Property implementation
public double Distance =>
Math.Sqrt(X * X + Y * Y);
}
class MainClass
{
static void PrintPoint(IPoint p)
{
Console.WriteLine("x={0}, y={1}", p.X, p.Y);
}
static void Main()
{
IPoint p = new Point(2, 3);
Console.Write("My Point: ");
PrintPoint(p);
}
}
// Output: My Point: x=2, y=3
C# 語言規格
欲了解更多資訊,請參閱 C# 語言規範中的介面部分及介面中靜態抽象成員的功能規範。