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

Rozhraní obsahuje definice pro skupinu souvisejících funkcí, které není abstraktní class nebo struct musí implementovat. Rozhraní může definovat static metody, které musí mít implementaci. Rozhraní může definovat výchozí implementaci členů. Rozhraní nemusí 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 schopnost je důležitá v jazyce C#, 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 pro metodu Equals , která odpovídá podpisu, který rozhraní určuje. 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 je rovna 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í mohou 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 můžou být static abstractčleny rozhraní, které nejsou poli. Rozhraní nemůže obsahovat pole instance, konstruktory instancí ani finalizační metody. Členy rozhraní jsou ve výchozím nastavení veřejné a můžete explicitně určit modifikátory přístupnosti, například public, , protectedinternal, private, , protected internalnebo 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ý, 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ím člen. Statický člen deklarovaný v typu nepřepíše statický člen deklarovaný v rozhraní.

Třída nebo struktura, která implementuje rozhraní musí poskytnout implementaci pro všechny deklarované členy bez výchozí implementace poskytované rozhraním. Pokud však základní třída implementuje rozhraní, každá třída odvozená od 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ý objekt get . Třída, která implementuje rozhraní, může deklarovat stejnou vlastnost s get a set accessor. Pokud však vlastnost nebo indexer používá explicitní implementaci, musí se přístupové objekty shodovat. Další informace o explicitní implementaci naleznete v tématu Explicit Interface Implementace a Vlastnosti rozhraní.

Rozhraní mohou dědit z jednoho nebo více rozhraní. Odvozené rozhraní dědí členy z jeho 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 jakékoli jeho základní rozhraní. Třída může zahrnovat rozhraní vícekrá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 implementuje, že rozhraní zdědí tuto implementaci (je nutné přetypovat instanci třídy na typ rozhraní pro přístup k výchozí implementaci č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 naleznete v tématu Polymorfismus.

Souhrn rozhraní

Rozhraní má následující vlastnosti:

  • Ve verzích C# starších než 8.0 se rozhraní podobá abstraktní základní třídě 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 ve výchozích metodách 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í.