Lekce 18 - Rozhraní (interface) v Javě
V minulé lekci, Diář s databází v Javě - Metody diáře, výjimky a final, jsme se podívali na metody třídy
Diar
, krátce koukli na výjimky a klíčové slovo final.
Dnes to 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 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 do arény. Třída Bojovnik
měla následující
veřejné metody:
void utoc(Bojovnik souper)
void branSe(int uder)
boolean jeZivy()
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 třeba třídu. Toto rozhraní poté použijeme jako datový typ.
Vše si vyzkoušíme, ale na něčem jednodušším, než je bojovník.
Vytvořme si nový projekt a nazvěme ho Rozhrani
. Přidáme si
nějakou jednoduchou třídu. Protože by se dle mého názoru měla teorie
vysvětlovat na něčem odlehčujícím, uděláme si třídu ptáka. Bude umět
pípat, dýchat a klovat. Přidejme si třídu Ptak
, bude vypadat
takto:
public class Ptak { public void pipni() { System.out.println("♫ ♫ ♫"); } public void dychej() { System.out.println("Dýchám..."); } public void klovni() { System.out.println("Klov, klov!"); } }
Třída je opravdu triviální. Přejděme do hlavního souboru
Rozhrani.java
s metodou main()
a vytvořme si instanci
ptáka:
Ptak ptak = new Ptak();
Nyní napíšeme ptak.
a necháme IDE, aby nám zobrazilo metody
na třídě (lze také vyvolat stiskem Ctrl + space):

Vidíme, co na ptákovi můžeme vše volat. Jsou tam samozřejmě ty 3 metody, co 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ého slova
interface
(česky rozhraní). Pojmenování rozhraní v Javě je
poměrně věda, my se spokojíme s názvem PtakInterface
:
Pravým tlačítkem klikneme na projekt, a klikneme na položku New
-> Java Class. V okně, které se otevře potom, přepneme
Class
na Interface
:

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) se uvádí až ve třídě, která bude toto rozhraní implementovat. Rozhraní vytváří pouze předpis metod, co musí třída implementovat.
Do rozhraní PtakInterface
tedy přidáme hlavičky metod,
schválně jednu vynecháme a přidáme pouze metody pro pípání a
dýchání:
public interface PtakInterface { void pipni(); void dychej(); }
Modifikátor public
neuvádíme, protože rozhraní obsahuje
vždy pouze veřejné metody. Jinak by to nemělo smysl, rozhraní udává, jak
s objektem zvenku pracovat.
Vraťme se do Rozhrani.java
a změňme řádek s proměnnou
ptak
tak, aby již nebyla typu Ptak
, ale
PtakInterface
:
PtakInterface ptak = new Ptak();
Kódem výše říkáme, že v proměnné typu PtakInterface
očekáváme objekt, který obsahuje ty metody, co jsou v rozhraní. IDE nám
vyhubuje, protože třída Ptak
zatím rozhraní
PtakInterface
neobsahuje, i když potřebné metody má, neví, že
rozhraní poskytuje. Přesuneme se do třídy Ptak
a nastavíme
jí, že implementuje interface PtakInterface
. Uděláme to
klíčovým slovem implements
:
public class Ptak implements PtakInterface { // ...
Když se nyní vrátíme do souboru Rozhrani.java
, řádek s
proměnnou typu PtakInterface
je již v pořádku, třída
Ptak
korektně implementuje rozhraní PtakInterface
a
její instance může být do proměnné tohoto typu uložena.
Zkusme nyní vymazat ze třídy Ptak
nějakou metodu, kterou
rozhraní udává, třeba pipni()
. IDE nás upozorní, že
implementace není kompletní. Vraťme ji zas zpět.
Opět přidáme řádek ptak.
do metody main()
v
souboru Rozhrani.java
, IDE nám nabídne následující metody:

Vidíme, že na instanci můžeme nyní volat pouze metody, které poskytuje
rozhraní. To proto, že proměnná ptak
je již typu
PtakInterface
, 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ám, že nemůžeme vytvořit instanci z rozhraní, tento kód nebude fungovat:
// tento kód nebude fungovat PtakInterface ptak = new PtakInterface();
Vícenásobná dědičnost
Java (stejně jako většina jazyků) nepodporuje vícenásobnou dědičnost. Nemůžeme tedy jednu třídu oddědit z několika jiných tříd. Je to hlavně z toho důvodu, že může vyvstat 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. Umožňuje nám to s instancí poté pracovat určitým způsobem a vůbec nás nezajímá, jakého typu objekt ve skutečnosti je a co všechno navíc obsahuje.
Přidejme si k projektu rozhraní JesterInterface
. Bude to
rozhraní ještěra. Ten bude umět také dýchat a ještě se plazit:
public interface JesterInterface { void plazSe(); void dychej(); }
Ptakoještěr
Vyzkoušejme si "vícenásobnou dědičnost", přesněji implementaci více
rozhraní v jedné třídě. Udělejme si ptakoještěra. Přidejme k projektu
třídu PtakoJester
. Bude implementovat rozhraní
PtakInterface
a JesterInterface
:
public class PtakoJester implements JesterInterface, PtakInterface { }
Když nyní klikneme na ikonu žárovky, můžeme v kontextovém menu zvolit možnost Implement methods. IntelliJ nám automaticky do třídy vygeneruje potřebné metody:

Po implementaci obou rozhraní může vypadat kód třídy takto (závisí na použitém IDE):
public class PtakoJester implements JesterInterface, PtakInterface { @Override public void plazSe() { throw new UnsupportedOperationException("Not supported yet."); } @Override public void dychej() { throw new UnsupportedOperationException("Not supported yet."); } @Override public void pipni() { throw new UnsupportedOperationException("Not supported yet."); } }
Všimněte si, že IDE přidalo notaci @Override
k metodám,
které implementují rozhraní. Je to tak přehlednější a klíčové slovo
@Override
si připíšeme i k metodám pipni()
a
dychej()
v třídě Ptak
.
Metody v třídě PtakoJester
doimplementujeme:
@Override public void plazSe() { System.out.println("Plazím se..."); } @Override public void dychej() { System.out.println("Dýchám..."); } @Override public void pipni() { System.out.println("♫ ♫♫ ♫ ♫ ♫♫"); }
Přesuňme se do Rozhrani.java
a vytvořme si instanci
ptakoještěra:
PtakoJester ptakojester = new PtakoJester();
Ujistěme se, že má metody jak ptáka, tak ještěra:

V příští lekci, Přetypování a hierarchie objektů v Javě, se naučíme 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 963x (11.7 kB)
Aplikace je včetně zdrojových kódů v jazyce Java