Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Rozhraní obsahuje definice pro skupinu souvisejících funkcí, které není abstraktní class nebo struct musí implementovat. Rozhraní může definovat static metody. Rozhraní může definovat výchozí implementaci pro členy. Rozhraní nemůže 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 typu T , která implementuje IEquatable<T> , aby obsahovala Equals metodu, se kterou může instance této 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. Členy rozhraní, které nejsou poli, můžou být static abstract. 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í pomocí implicitní implementace, musí být odpovídající člen implementační třídy veřejný, nestatický a musí mít stejný název a podpis jako člen rozhraní. K implementaci členů rozhraní, které nemají být veřejné, musíte použít explicitní implementaci rozhraní.
Poznámka:
Když rozhraní deklaruje statické členy, typ, který implementuje toto rozhraní, může také deklarovat statické členy se stejným podpisem. Ti členové jsou jedineční a jednoznačně identifikovaní typem deklarujícím člena. 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á 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 deklarovaný 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.
Práce s interními rozhraními
Interní rozhraní lze obvykle implementovat pomocí implicitní implementace s veřejnými členy, pokud jsou všechny typy v podpisu rozhraní veřejně přístupné. Pokud však rozhraní používá interní typy v podpisech členů, implicitní implementace se stane nemožná, protože implementující člen třídy bude muset být veřejný při zveřejnění interních typů. V takových případech musíte použít explicitní implementaci rozhraní.
Následující příklad ukazuje oba scénáře:
// Internal type that cannot be exposed publicly
internal class InternalConfiguration
{
public string Setting { get; set; } = "";
}
// Internal interface that CAN be implemented with public members
// because it only uses public types in its signature
internal interface ILoggable
{
void Log(string message); // string is public, so this works with implicit implementation
}
// Interface with internal accessibility using internal types
internal interface IConfigurable
{
void Configure(InternalConfiguration config); // Internal type prevents implicit implementation
}
// This class shows both implicit and explicit interface implementation
public class ServiceImplementation : ILoggable, IConfigurable
{
// Implicit implementation works for ILoggable because string is public
public void Log(string message)
{
Console.WriteLine($"Log: {message}");
}
// Explicit implementation required for IConfigurable because it uses internal types
void IConfigurable.Configure(InternalConfiguration config)
{
// Implementation here
Console.WriteLine($"Configured with: {config.Setting}");
}
// If we tried implicit implementation for IConfigurable, this wouldn't compile:
// public void Configure(InternalConfiguration config) // Error: cannot expose internal type
}
V předchozím příkladu IConfigurable rozhraní používá interní typ InternalConfiguration v podpisu metody.
ServiceImplementation Třída nemůže použít implicitní implementaci, protože by vyžadovala, Configure aby byla metoda veřejná, což není povoleno, pokud podpis metody obsahuje interní typy. Místo toho se používá explicitní implementace rozhraní, která nemá modifikátor přístupu a je přístupná pouze prostřednictvím typu rozhraní.
Naproti tomu lze rozhraní implicitně implementovat s veřejnými členy, protože všechny typy v jeho podpisu (ILoggable) jsou veřejně přístupné, i když samotné rozhraní je interní.
Další informace o explicitní implementaci rozhraní naleznete v tématu explicitní implementace rozhraní.
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 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.
- 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í.