Rozhraní – definování chování pro více typů
Rozhraní obsahuje definice pro skupinu souvisejících funkcí, které nejsou class
abstraktní nebo struct
musí implementovat. Rozhraní může definovat static
metody, které musí mít implementaci. Rozhraní může definovat výchozí implementaci pro členy. Rozhraní nesmí deklarovat data instance, jako jsou pole, automaticky implementované vlastnosti nebo události podobné vlastnostem.
Pomocí rozhraní můžete například zahrnout chování z více zdrojů ve třídě. Tato funkce je v jazyce C# důležitá, protože jazyk nepodporuje více dědičnosti tříd. Kromě toho musíte použít rozhraní, pokud chcete simulovat dědičnost struktur, protože ve skutečnosti nemohou dědit z jiné struktury nebo třídy.
Rozhraní definujete pomocí klíčového interface
slova, jak ukazuje následující příklad.
interface IEquatable<T>
{
bool Equals(T obj);
}
Název rozhraní musí být platný název identifikátoru jazyka C#. Podle konvence názvy rozhraní začínají velkým písmenem I
.
Jakákoli třída nebo struktura, která implementuje IEquatable<T> rozhraní, musí obsahovat definici pro metodu Equals , která odpovídá podpisu, který rozhraní určuje. V důsledku toho se můžete spolehnout na třídu, která implementuje IEquatable<T>
, aby obsahovala metodu Equals
, pomocí které instance třídy může určit, zda je rovna jiné instanci stejné třídy.
Definice parametru IEquatable<T>
neposkytuje implementaci pro Equals
. Třída nebo struktura může implementovat více rozhraní, ale třída může dědit pouze z jedné třídy.
Další informace o abstraktních třídách najdete v tématu Abstraktní a zapečetěné třídy a Členy tříd.
Rozhraní mohou obsahovat metody instancí, vlastnosti, události, indexery nebo libovolnou kombinaci těchto čtyř typů členů. Rozhraní mohou obsahovat statické konstruktory, pole, konstanty nebo operátory. Počínaje jazykem C# 11 můžou být členy rozhraní, které nejsou poli, .static abstract
Rozhraní nemůže obsahovat pole instance, konstruktory instancí ani finalizátory. Členy rozhraní jsou ve výchozím nastavení veřejné a můžete explicitně zadat modifikátory přístupnosti, například public
, protected
, internal
, private
, protected internal
nebo private protected
. Člen private
musí mít výchozí implementaci.
Chcete-li implementovat člen rozhraní, odpovídající člen implementované třídy musí být veřejný, nestatický a musí mít stejný název a podpis jako člen rozhraní.
Poznámka
Když rozhraní deklaruje statické členy, typ implementuje toto rozhraní může také deklarovat statické členy se stejným podpisem. Ty jsou jedinečné a jednoznačně identifikované typem deklarujícího člena. Statický člen deklarovaný v typu nepřepíše statický člen deklarovaný v rozhraní.
Třída nebo struktura, která implementuje rozhraní, musí poskytovat implementaci pro všechny deklarované členy bez výchozí implementace poskytované rozhraním. Pokud však základní třída implementuje rozhraní, zdědí tuto implementaci jakákoli třída, která je odvozena ze základní třídy.
Následující příklad ukazuje implementaci IEquatable<T> rozhraní. Implementační třída Car
, musí poskytovat implementaci Equals metody.
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);
}
}
Vlastnosti a indexery třídy mohou definovat další přístupové objekty pro vlastnost nebo indexer, který je definován v rozhraní. Rozhraní může například deklarovat vlastnost, která má get accessor . Třída, která implementuje rozhraní, může deklarovat stejnou vlastnost s a get
set accessor. Pokud však vlastnost nebo indexer používá explicitní implementaci, musí se přístupové objekty shodovat. Další informace o explicitní implementaci najdete v tématu explicitní implementace rozhraní a vlastnosti rozhraní.
Rozhraní mohou dědit z jednoho nebo více rozhraní. Odvozené rozhraní dědí členy ze svých základních rozhraní. Třída, která implementuje odvozené rozhraní, musí implementovat všechny členy v odvozené rozhraní, včetně všech členů základní rozhraní odvozeného rozhraní. Tato třída může být implicitně převedena na odvozené rozhraní nebo některé z jeho základních rozhraní. Třída může obsahovat rozhraní několikrát prostřednictvím základních tříd, které dědí, nebo prostřednictvím rozhraní, která dědí jiná rozhraní. Třída však může poskytnout implementaci rozhraní pouze jednou a pouze v případě, že třída deklaruje rozhraní jako součást definice třídy (class ClassName : InterfaceName
). Pokud je rozhraní zděděno, protože jste zdědili základní třídu, která implementuje rozhraní, základní třída poskytuje implementaci členů rozhraní. Odvozená třída však může reimplementovat všechny členy virtuálního rozhraní místo použití zděděné implementace. Když rozhraní deklarují výchozí implementaci metody, každá třída implementuje toto rozhraní zdědí tuto implementaci (Musíte přetypovat instanci třídy na typ rozhraní, abyste získali přístup k výchozí implementaci na člen rozhraní).
Základní třída může také implementovat členy rozhraní pomocí virtuálních členů. V takovém případě může odvozená třída změnit chování rozhraní přepsáním virtuálních členů. Další informace o virtuálních členech najdete v tématu Polymorfismus.
Souhrn rozhraní
Rozhraní má následující vlastnosti:
- Ve verzích jazyka C# starších než 8.0 je rozhraní jako abstraktní základní třída s pouze abstraktními členy. Třída nebo struktura, která implementuje rozhraní, musí implementovat všechny své členy.
- Počínaje jazykem C# 8.0 může rozhraní definovat výchozí implementace pro některé nebo všechny jeho členy. Třída nebo struktura, která implementuje rozhraní, nemusí implementovat členy, které mají výchozí implementace. Další informace najdete v tématu o výchozích metodách rozhraní.
- Rozhraní není možné vytvořit přímou instanci. Jeho členy jsou implementovány jakoukoli třídou nebo strukturou, která implementuje rozhraní.
- Třída nebo struktura může implementovat více rozhraní. Třída může dědit základní třídu a také implementovat jedno nebo více rozhraní.