NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!
NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.

Lekce 15 - Rozhraní (interface)

V minulé lekci, Diář s databází v C#, jsme si procvičili práci s kolekcí List při tvorbě elektronického diáře.

Dnešní C# tutoriál bude opět trochu teoretický. Objevíme další taje objektově orientovaného programování, uvedeme si totiž rozhraní.

Rozhraní

Rozhraním objektu se myslí to, jak je objekt viditelný zvenku. Již víme, že objekt obsahuje nějaké metody, ty mohou být buď privátní, nebo veřejné. Rozhraní objektu tvoří právě jeho veřejné metody. Je to způsob, jakým s určitým typem objektu můžeme komunikovat. Již jsme několikrát mohli vidět, jaké veřejné metody naše třída nabízí, např. u našeho bojovníka v aréně. Třída Bojovnik měla následující veřejné metody:

  • void Utoc(Bojovnik souper),
  • void BranSe(int uder),
  • bool Nazivu(),
  • void NastavZpravu(string zprava),
  • string VratPosledniZpravu(),
  • string GrafickyZivot().

Pokud si do nějaké proměnné uložíme instanci bojovníka, můžeme na ni volat metody jako Utoc() nebo BranSe(). To pořád není nic nového, že?

My si však rozhraní můžeme deklarovat zvlášť, a to podobným způsobem jako např. třídu. Toto rozhraní poté použijeme jako datový typ.

Vše si nyní vyzkoušíme, avšak na něčem jednodušším, než je bojovník. Vytvořme si nový projekt, a sice konzolovou aplikaci, a nazvěme ho Rozhrani. Přidejme si nějakou jednoduchou třídu. Protože by se dle našeho názoru měla teorie vysvětlovat na něčem odlehčeném, vytvoříme si ptáka. Ten bude umět pípat, dýchat a klovat. Přidejme si třídu Ptak, která bude vypadat takto:

class Ptak
{

    public void Pipni()
    {
        Console.WriteLine("♫ ♫ ♫");
    }

    public void Dychej()
    {
        Console.WriteLine("Dýchám...");
    }

    public void Klovni()
    {
        Console.WriteLine("Klov, klov!");
    }

}

Třída je opravdu triviální. Přejděme do Program.cs a vytvořme si instanci ptáka:

Ptak ptak = new Ptak();

Nyní napíšeme ptak. a necháme Visual Studio, aby nám zobrazilo metody na třídě (lze také vyvolat stiskem Ctrl + Space):

Metody ptáka - Objektově orientované programování v C# .NET

Vidíme, co vše můžeme na ptákovi volat. K dispozici jsou samozřejmě ony tři metody, které jsme ve třídě implementovali (plus další, které mají objekty v základu).

Nyní ptákovi vytvoříme rozhraní. Využijeme k tomu klíčové slovo interface (anglicky rozhraní). Je dobrým zvykem, že rozhraní v C# začíná vždy na písmeno I (jako Interface). Vytvořme tedy interface IPtak. Pravým tlačítkem klikneme na projekt a přidáme nový item -> Interface.

Nové interface ve Visual Studiu - Objektově orientované programování v C# .NET

K projektu se nám přidá prázdné interface. Do něj přidáme hlavičky metod, které má dané rozhraní obsahovat. Samotnou implementaci (kód metod) uvedeme až ve třídě, která bude toto rozhraní implementovat (viz dále).

Do rozhraní IPtak tedy přidáme hlavičky metod. Záměrně jednu vynecháme a přidáme pouze pípání a dýchání:

interface IPtak
{
    void Pipni();
    void Dychej();
}

Modifikátor public neuvádíme, protože rozhraní obsahuje vždy pouze veřejné metody (jinak by nemělo smysl, jak již víme, rozhraní udává, jak s objektem pracovat zvenku).

Vraťme se do Program.cs a změňme řádek s proměnnou ptak tak, aby již nebyla typu Ptak, ale IPtak:

IPtak ptak = new Ptak();

Kódem výše říkáme, že v proměnné typu IPtak očekáváme objekt, který obsahuje ty metody, jež jsou v rozhraní. Visual Studio nám vyhubuje, protože třída Ptak zatím rozhraní IPtak neobsahuje. Přestože třída Ptak potřebné metody má, neví, že poskytuje rozhraní. Přesuneme se tedy do třídy Ptak a nastavíme jí, že implementuje interface IPtak. To se dělá stejně, jako když třída od jiné dědí:

class Ptak: IPtak
{
    // . . .

Když se nyní vrátíme do Program.cs, řádek s proměnnou typu IPtak je již v pořádku. Třída Ptak korektně implementuje rozhraní IPtak a její instance může být do proměnné tohoto typu uložena.

Zkusme nyní vymazat ze třídy nějakou metodu, kterou rozhraní udává, např. Pipni(). Visual Studio nás upozorní, že implementace není kompletní. Vraťme metodu zase zpět.

Opět přidáme řádek ptak., Visual Studio nám nabídne následující metody:

Metody ptáka s rozhraním IPtak - Objektově orientované programování v C# .NET

Vidíme, že na instanci můžeme nyní volat pouze metody, které poskytuje rozhraní. To proto, že proměnná ptak je již typu IPtak, nikoli Ptak. Metoda Klovni() úplně chybí.

K čemu je to dobré? Výhod a využití je více, na první jsme již přišli. Pomocí rozhraní dokážeme zjednodušit rozhraní nějakého složitého objektu a vystavit jen tu část, která se nám v tu dobu hodí.

Ještě dodáme, že nemůžeme vytvořit instanci z rozhraní, tento kód nebude fungovat:

// tento kód nebude fungovat
IPtak ptak = new IPtak();

Vícenásobná dědičnost

C# (stejně jako většina programovacích jazyků) nepodporuje vícenásobnou dědičnost. Nemůžeme tedy jednu třídu podědit z několika jiných tříd. Je to hlavně z toho důvodu, že může nastat problém kolize názvů metod v různých třídách, ze kterých dědíme. Vícenásobná dědičnost se často obchází právě přes interface, protože těch můžeme ve třídě implementovat, kolik chceme. To nám poté umožňuje s instancí pracovat určitým způsobem a vůbec nás nemusí zajímat, jakého typu objekt ve skutečnosti je a co všechno navíc obsahuje.

Přidejme si k projektu interface IJester. Bude to interface ještěra. Ten bude umět také dýchat a ještě se plazit:

interface IJester
{
    void PlazSe();
    void Dychej();
}

Vyzkoušejme si „vícenásobnou dědičnost“, přesněji implementaci více rozhraní v jedné třídě. Vytvořme si ptakoještěra. Přidejme k projektu třídu PtakoJester.cs. Ta bude implementovat rozhraní IPtak a IJester:

class PtakoJester: IJester, IPtak
{
}

Když nyní klikneme v tomto kódu pravým tlačítkem na jednotlivá interface (tedy na IJester a IPtak), můžeme v kontextovém menu zvolit možnost Implement Interface. Visual Studio nám poté do třídy automaticky vygeneruje potřebné metody.

Automatická implementace - Objektově orientované programování v C# .NET

Po implementaci obou rozhraní vypadá kód třídy takto:

class PtakoJester: IJester, IPtak
{
    public void PlazSe()
    {
        throw new NotImplementedException();
    }

    public void Dychej()
    {
        throw new NotImplementedException();
    }

    public void Pipni()
    {
        throw new NotImplementedException();
    }
}

Metody doimplementujeme:

public void PlazSe()
{
    Console.WriteLine("Plazím se...");
}

public void Dychej()
{
    Console.WriteLine("Dýchám...");
}

public void Pipni()
{
    Console.WriteLine("♫ ♫♫ ♫ ♫ ♫♫");
}

Přesuňme se do Program.cs a vytvořme si instanci ptakoještěra:

PtakoJester ptakojester = new PtakoJester();

Ujistěme se, že instance má metody jak ptáka, tak ještěra:

Metody ptáka a ještěra - Objektově orientované programování v C# .NET

V příští lekci, Přetypování a hierarchie objektů, budeme pokračovat v podobném duchu. Rozhraní ještě neopustíme a naučíme se další pokročilé techniky objektově orientovaného programování.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 1142x (23.49 kB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

Předchozí článek
Diář s databází v C#
Všechny články v sekci
Objektově orientované programování v C# .NET
Přeskočit článek
(nedoporučujeme)
Přetypování a hierarchie objektů
Článek pro vás napsal David Hartinger
Avatar
Uživatelské hodnocení:
433 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity