interface (Referenční dokumentace jazyka C#)
Rozhraní definuje kontrakt. Jakékoli class
nebo record
struct
implementované kontrakty musí poskytnout implementaci členů definovaných v rozhraní. Rozhraní může definovat výchozí implementaci členů. Může také definovat static
členy, aby poskytovala jednu implementaci pro společné funkce. Počínaje C# 11 může rozhraní definovat static abstract
nebo static virtual
členy deklarovat, že implementovaný typ musí poskytovat deklarované členy. Metody obvykle deklarují, static virtual
že implementace musí definovat sadu přetížených operátorů.
V následujícím příkladu musí třída ImplementationClass
implementovat metodu s názvem SampleMethod
, která nemá žádné parametry a vrací void
.
Další informace a příklady najdete v tématu Rozhraní.
Rozhraní nejvyšší úrovně, které je deklarováno v oboru názvů, ale není vnořené uvnitř jiného typu, lze deklarovat public
nebo internal
. Výchozí hodnota je internal
. Deklarace vnořeného rozhraní, deklarované uvnitř jiného typu, lze deklarovat pomocí libovolného modifikátoru přístupu.
Členy rozhraní bez implementace nemůžou obsahovat modifikátor přístupu. Členové s výchozí implementací mohou obsahovat libovolný modifikátor přístupu.
Ukázkové rozhraní
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();
}
}
Rozhraní může být členem oboru názvů nebo třídy. Deklarace rozhraní může obsahovat deklarace (podpisy bez jakékoli implementace) následujících členů:
Výchozí členové rozhraní
Tyto předchozí deklarace členů obvykle neobsahují tělo. Člen rozhraní může deklarovat tělo. Výchozí implementací jsou členské subjekty v rozhraní. Členové s subjekty umožňují rozhraní poskytnout "výchozí" implementaci tříd a struktur, které neposkytují přepsání implementace.
Důležité
Přidání výchozích rozhraní vynutí, aby všechny ref struct
, které implementují rozhraní, přidal explicitní deklaraci tohoto členu.
Rozhraní může zahrnovat:
- Konstanty
- Operátory
- Statický konstruktor.
- Vnořené typy
- Statická pole, metody, vlastnosti, indexery a události
- Deklarace členů používající syntaxi implementace explicitního rozhraní.
- Modifikátory explicitního přístupu (výchozí přístup je
public
).
Statické abstraktní a virtuální členy
Počínaje jazykem C# 11 může rozhraní deklarovat static abstract
a static virtual
členy pro všechny typy členů s výjimkou polí. Rozhraní mohou deklarovat, že implementace typů musí definovat operátory nebo jiné statické členy. Tato funkce umožňuje obecným algoritmům určit chování podobné číslům. Příklady můžete zobrazit v číselných typech v modulu runtime .NET, například System.Numerics.INumber<TSelf>. Tato rozhraní definují běžné matematické operátory implementované mnoha číselnými typy. Kompilátor musí vyřešit volání a static virtual
static abstract
metody v době kompilace. Metody static virtual
deklarované static abstract
v rozhraních nemají mechanismus dispečerského modulu runtime, který je podobný virtual
metodám nebo abstract
metodám deklarovaným ve třídách. Místo toho kompilátor používá informace o typu dostupné v době kompilace. static virtual
Proto jsou metody téměř výhradně deklarovány v obecných rozhraních. Kromě toho většina rozhraní, která deklarují nebo metody deklarujístatic virtual
, že jeden z parametrů typu musí implementovat deklarované rozhraní.static abstract
Například INumber<T>
rozhraní deklaruje, že T
musí implementovat INumber<T>
. Kompilátor používá argument typu k překladu volání metod a operátorů deklarovaných v deklaraci rozhraní. Například int
typ implementuje INumber<int>
. Když parametr T
typu označuje argument int
typu, static
jsou vyvolány členy deklarované na int
. Alternativně platí, že pokud double
je argument typu, static
jsou vyvolány členy deklarované v double
typu.
Důležité
Volání metody pro static abstract
a static virtual
metody deklarované v rozhraních je vyřešeno pomocí typu času kompilace výrazu. Pokud je typ modulu runtime výrazu odvozen z jiného typu času kompilace, budou volána statické metody základního typu (čas kompilace).
Tuto funkci můžete vyzkoušet pomocí kurzu o statických abstraktních členech v rozhraních.
Dědičnost rozhraní
Rozhraní nemusí obsahovat stav instance. I když jsou teď statická pole povolená, pole instancí nejsou v rozhraních povolená. Automatické vlastnosti instance nejsou v rozhraních podporované, protože by implicitně deklarovaly skryté pole. Toto pravidlo má malý vliv na deklarace vlastností. V deklaraci rozhraní následující kód deklaruje automaticky implementovanou vlastnost jako v objektu nebo class
struct
. Místo toho deklaruje vlastnost, která nemá výchozí implementaci, ale musí být implementována v jakémkoli typu, který implementuje rozhraní:
public interface INamed
{
public string Name {get; set;}
}
Rozhraní může dědit z jednoho nebo více základních rozhraní. Když rozhraní dědí z jiného rozhraní, musí typ implementovaný odvozeným rozhraním implementovat všechny členy v základních rozhraních i ty deklarované v odvozené rozhraní, jak je znázorněno v následujícím kódu:
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() { }
}
Pokud rozhraní přepíše metodu implementovanou v základním rozhraní, musí použít explicitní syntaxi implementace rozhraní.
Jestliže seznam základních typů obsahuje základní třídu a rozhraní, musí se základní třída nacházet v seznamu jako první.
Třída, která implementuje rozhraní, může explicitně implementovat členy rozhraní. Explicitně implementovaný člen není přístupný prostřednictvím instance třídy, ale pouze prostřednictvím instance rozhraní. Kromě toho je možné k výchozím členům rozhraní přistupovat pouze prostřednictvím instance rozhraní.
Další informace o explicitní implementaci rozhraní naleznete v tématu explicitní implementace rozhraní.
Příklad implementace rozhraní
Následující příklad ukazuje implementaci rozhraní. V tomto příkladu obsahuje rozhraní deklaraci vlastnosti a třída obsahuje implementaci. Jakákoli instance třídy, která implementuje rozhraní IPoint
, má celočíselné vlastnosti x
a 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
specifikace jazyka C#
Další informace najdete v části Rozhraní specifikace jazyka C#, specifikace funkce pro C# 8 – výchozí členy rozhraní a specifikace funkce pro C# 11 – statické abstraktní členy v rozhraních.