Rozhraní – definování chování pro více typů

Rozhraní obsahuje definice pro skupinu souvisejících funkcí, které nejsou abstraktní class nebo struct musí implementovat. Rozhraní může definovat static metody, které musí mít implementaci. Počínaje jazykem C# 8.0 může rozhraní definovat výchozí implementaci členů. Rozhraní nemusí deklarovat data instance, jako jsou pole, automaticky implementované vlastnosti nebo události podobné vlastnosti.

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 pro struktury, protože nemohou ve skutečnosti 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 začínají názvy rozhraní velkým písmenem I.

Každá třída nebo struktura, která implementuje IEquatable<T> rozhraní, musí obsahovat definici metody Equals , která odpovídá podpisu, který určuje rozhraní. V důsledku toho můžete počítat s třídou, která implementuje IEquatable<T> , aby obsahovala Equals metodu, se kterou může instance třídy určit, zda se rovná jiné instanci stejné třídy.

Definice 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 naleznete v tématu Abstraktní a zapečetěné třídy a členy třídy.

Rozhraní můžou obsahovat metody, 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 mohou být static abstractčleny rozhraní, které nejsou poli . Rozhraní nemůže obsahovat pole instancí, konstruktory instancí ani finalizátory. Členové rozhraní jsou ve výchozím nastavení veřejné a můžete explicitně určit modifikátory přístupnosti, například public, , protected, , protected internalinternalprivatenebo .private protected Člen private musí mít výchozí implementaci.

Aby bylo možné implementovat člen rozhraní, musí být odpovídající člen implementované třídy veřejný, ne statická 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. Jedná se o 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 ale základní třída implementuje rozhraní, každá třída odvozená ze základní třídy dědí tuto implementaci.

Následující příklad ukazuje implementaci IEquatable<T> rozhraní. Implementační třída , Carmusí poskytnout 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á přístupové objekty get . Třída, která implementuje rozhraní, může deklarovat stejnou vlastnost s get a set accessor. Pokud ale vlastnost nebo indexer používá explicitní implementaci, musí se přístupové objekty shodovat. Další informace o explicitní implementaci naleznete 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ích rozhraní odvozeného rozhraní. Tato třída může být implicitně převedena na odvozené rozhraní nebo jakékoli jeho základní rozhraní. Třída může zahrnovat rozhraní několikrát prostřednictvím základních tříd, které dědí nebo prostřednictvím rozhraní, která ostatní rozhraní dědí. 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í namísto použití zděděné implementace. Když rozhraní deklarují výchozí implementaci metody, každá třída implementovaná toto rozhraní dědí tuto implementaci (pro přístup k výchozí implementaci člena rozhraní je nutné přetypovat instanci třídy na typ 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 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 jeho č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 výchozí metody rozhraní.
  • Rozhraní nelze vytvořit přímo. Jeho členy jsou implementovány libovolnou 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í.