Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Interfejs definiuje kontrakt. Każdy classelement , recordlub struct implementujący ten kontrakt musi zapewnić implementację elementów członkowskich zdefiniowanych w interfejsie.
Interfejs może definiować domyślną implementację elementu członkowskiego. Może również definiować static elementy członkowskie w celu zapewnienia jednej implementacji dla typowych funkcji.
Interfejs może definiować static abstract elementy członkowskie lub static virtual zadeklarować, że typ implementujący musi podać zadeklarowane elementy członkowskie. Zazwyczaj metody deklarują, static virtual że implementacja musi definiować zestaw przeciążonych operatorów.
W poniższym przykładzie klasa ImplementationClass musi zaimplementować metodę o nazwie SampleMethod , która nie ma parametrów i zwraca wartość 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();
}
}
Aby uzyskać więcej informacji i przykładów, zobacz Interfejsy.
Modyfikatory dostępu
Interfejs może być elementem członkowskim przestrzeni nazw lub klasy. Interfejs najwyższego poziomu, zadeklarowany w przestrzeni nazw, ale nie zagnieżdżony wewnątrz innego typu, można zadeklarować public lub internal. Wartość domyślna to internal. Deklaracje interfejsu zagnieżdżonego zadeklarowane wewnątrz innego typu można zadeklarować przy użyciu dowolnego modyfikatora dostępu.
Elementy członkowskie interfejsu bez implementacji (abstrakcyjne elementy członkowskie) są niejawnie public i nie mogą mieć żadnego innego modyfikatora dostępu. Elementy członkowskie interfejsu z domyślną implementacją są private domyślnie, jeśli nie określono modyfikatora dostępu, ale można je zadeklarować za pomocą dowolnego modyfikatora dostępu (public, private, protectedlub internal).
Składniki interfejsu
Deklaracja interfejsu może zawierać następujące elementy członkowskie:
- Metody.
- Właściwości.
- Indeksatory.
- Zdarzenia.
- Stałe.
- Operatory.
- Konstruktor statyczny.
- Typy zagnieżdżone.
- Pola statyczne, metody, właściwości, indeksatory i zdarzenia.
- Modyfikatory dostępu jawnego (domyślny dostęp dla metod abstrakcyjnych to
public).
Domyślne elementy członkowskie interfejsu
Deklaracje składowe zwykle nie zawierają treści, jednak element członkowski interfejsu może zadeklarować treść. Elementy członkowskie w interfejsie są domyślną implementacją. Elementy członkowskie z ciałami umożliwiają interfejsowi zapewnienie implementacji "domyślnej" dla klas i struktur, które nie zapewniają zastępowania implementacji.
Ważne
Dodanie domyślnych elementów członkowskich wymusza każdą ref struct implementację interfejsu w celu dodania jawnej deklaracji tego elementu członkowskiego.
Statyczne abstrakcyjne i wirtualne elementy członkowskie
Interfejs może deklarować static abstract i static virtual składowe dla wszystkich typów elementów członkowskich z wyjątkiem pól. Interfejsy mogą zadeklarować, że typy implementujące muszą definiować operatory lub inne statyczne elementy członkowskie. Ta funkcja umożliwia ogólne algorytmy określania zachowania przypominającego liczbę. Przykłady można zobaczyć w typach liczbowych w środowisku uruchomieniowym platformy .NET, takich jak System.Numerics.INumber<TSelf>. Te interfejsy definiują typowe operatory matematyczne implementowane przez wiele typów liczbowych. Kompilator musi rozpoznawać wywołania metod static virtual i w static abstract czasie kompilacji. Metody static virtual i static abstract zadeklarowane w interfejsach nie mają mechanizmu wysyłania środowiska uruchomieniowego analogicznego do virtual lub abstract metod zadeklarowanych w klasach. Zamiast tego kompilator używa informacji o typie dostępnych w czasie kompilacji. W związku z static virtual tym metody są prawie wyłącznie deklarowane w interfejsach ogólnych. Ponadto większość interfejsów, które deklarują metody lub deklarująstatic virtual, że jeden z parametrów typu musi implementować static abstract. Na przykład interfejs deklaruje, INumber<T> że T musi implementować INumber<T>element . Kompilator używa argumentu typu do rozpoznawania wywołań metod i operatorów zadeklarowanych w deklaracji interfejsu. Na przykład int typ implementuje INumber<int>wartość . Gdy parametr T typu oznacza argument inttypu , static wywoływane są elementy członkowskie zadeklarowane int na. Alternatywnie, gdy double jest argumentem typu, static elementy członkowskie zadeklarowane w typie double są wywoływane.
Ważne
Wysyłanie metody dla static abstract metod zadeklarowanych w interfejsach i static virtual jest rozpoznawane przy użyciu typu czasu kompilacji wyrażenia. Jeśli typ środowiska uruchomieniowego wyrażenia pochodzi z innego typu czasu kompilacji, wywoływane są metody statyczne w typie podstawowym (czas kompilacji).
Tę funkcję można wypróbować, pracując z samouczkiem dotyczącym statycznych abstrakcyjnych elementów członkowskich w interfejsach.
Dziedziczenie interfejsu
Interfejsy nie mogą zawierać stanu wystąpienia. Pola statyczne są teraz dozwolone, ale pola wystąpień nie są dozwolone w interfejsach.
Właściwości automatyczne wystąpienia nie są obsługiwane w interfejsach, ponieważ niejawnie deklarują ukryte pole. Ta reguła ma subtelny wpływ na deklaracje właściwości. W deklaracji interfejsu poniższy kod nie deklaruje automatycznie zaimplementowanej właściwości, tak jak w obiekcie class lub struct. Zamiast tego deklaruje właściwość, która nie ma implementacji domyślnej, ale musi być zaimplementowana w dowolnym typie, który implementuje interfejs:
public interface INamed
{
public string Name {get; set;}
}
Interfejs może dziedziczyć z co najmniej jednego interfejsu podstawowego. Gdy interfejs dziedziczy z innego interfejsu, typ implementowania interfejsu pochodnego musi implementować wszystkie elementy członkowskie w interfejsach podstawowych oprócz tych elementów członkowskich zadeklarowanych w interfejsie pochodnym, jak pokazano w poniższym kodzie:
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() { }
}
Gdy interfejs zastępuje metodę zaimplementowaną w interfejsie podstawowym, musi używać jawnej składni implementacji interfejsu.
Gdy lista typów podstawowych zawiera klasę bazową i interfejsy, klasa bazowa musi znajdować się na liście jako pierwsza.
Klasa, która implementuje interfejs, może jawnie implementować elementy członkowskie tego interfejsu. Jawnie zaimplementowany element członkowski nie może być dostępny za pośrednictwem wystąpienia klasy, ale tylko za pośrednictwem wystąpienia interfejsu. Ponadto dostęp do domyślnych elementów członkowskich interfejsu można uzyskać tylko za pośrednictwem wystąpienia interfejsu.
Aby uzyskać więcej informacji na temat jawnej implementacji interfejsu, zobacz Jawna implementacja interfejsu.
Przykładowa implementacja interfejsu
W poniższym przykładzie pokazano implementację interfejsu. W tym przykładzie interfejs zawiera deklarację właściwości, a klasa zawiera implementację. Każde wystąpienie klasy, która implementuje, ma właściwości IPoint liczb całkowitych x i 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
specyfikacja języka C#
Aby uzyskać więcej informacji, zobacz sekcję Interfejsyspecyfikacji języka C# i specyfikację funkcji statycznych elementów abstrakcyjnych w interfejsach.