Mikuláš je tu! Získaj 90 % extra kreditov ZADARMO s promo kódom CERTIK90 pri nákupe od 1 199 kreditov. Len do nedele 7. 12. 2025! Zisti viac:
NOVINKA: Najžiadanejšie rekvalifikačné kurzy teraz s 50% zľavou + kurz AI ZADARMO. Nečakaj, táto ponuka dlho nevydrží! Zisti viac:

Diskusia – 19. diel - Rozhranie (interface) v Jave

Späť

Upozorňujeme, že diskusie pod našimi online kurzami sú nemoderované a primárne slúžia na získavanie spätnej väzby pre budúce vylepšenie kurzov. Pre študentov našich rekvalifikačných kurzov ponúkame možnosť priameho kontaktu s lektormi a študijným referentom pre osobné konzultácie a podporu v rámci ich štúdia. Toto je exkluzívna služba, ktorá zaisťuje kvalitnú a cielenú pomoc v prípade akýchkoľvek otázok alebo projektov.

Komentáre
Posledné komentáre sú na spodnej časti poslednej stránky.
Avatar
Odpovedá na Ondřej Havlíček
Petr Štechmüller:23.6.2023 17:44

Ahoj, zkusím to vysvětlit kompletně mimo kontext článku.

Řekněme, že máme rozhraní Auto. Aut může být několik značek (tříd implementující rozhraní Auto): "Skoda", "Audi", "Citroen".

Rozhraní Auto bude mít jednu metodu maximalniRychlost(), která vrátí maximální rychlost auta.

Dále budeme mít speciální třídu reprezentující továrnu na auta TovarnaAut, která bude vytvářet auta pomocí metody vytvorAuto(String typAuta). Návratový typ této metody bude rozhraní Auto, protože tebe jako uživatele pak nezajímá konkrétní implementace rozhraní, ale pouze metody, které to rozhraní poskytuje.

Takže pak by kód vypadal přibližně takto:

TovarnaAut tovarnaAut = new TovarnaAut();
Auto skoda = tovarnaAut.vytvorAuto("Skoda");
Auto audi = tovarnaAut.vytvorAuto("Audi");

int maxRychlostSkody = skoda.maximalniRychlost();
int maxRychlostAudi = audi.maximalniRychlost();

...

Myšlenka je taková, že v reálném projektu se neprogramuje vůče konkrétním třídám, ale vůči rozhraní, přičemž neřešíš, jaká je implementace rozhraní.

Proto až budeš probírat kolekce tak zjistíš, že existuje rozhraní List, které je implementováno různými třídami: ArrayList a LinkedList. Obě třídy poskytují implementaci metod z rozhraní List, jen trochu jinak.

Odpovedať
Pokud spolu kód a komentář nekorespondují, budou patrně oba chybné
Avatar
Odpovedá na Petr Štechmüller
Ondřej Havlíček:23.6.2023 18:34

Uff, no, abych pravdu řekl, pořád tomu teda nerozumím. Buď mi chybí ještě nějaký kus látky a nebo mám zkrátka o kolečko míň.

V článku bylo psáno, že rozhraní nejde instanciovat - nejde založit konstruktor. Jak je tedy možné, že bude metoda vytvorAuto() (která je ve třídě TovarnaAut) vracet instanci rozhraní Auto?
Navíc, metody nemůžou mít body (tělo), jak pak může metoda maximalniRychlost() rozhraní Auto, vracet nějakou hodnotu?

Nevím, jestli toho po Tobě nebudu chtít moc, ale mohl bys, prosím, nastínit kompletní funkční kód Tebou navrženého příkladu výše?

Editované
Avatar
Odpovedá na Ondřej Havlíček
Petr Štechmüller:23.6.2023 19:38

To je právě to kouzlo rozhraní. Nemusíš vědět, jak instance vznikla (nemusíš znát implementaci). Stačí ti jen, že to dělá to, co potřebuješ.

Kdybychom se ale podívali "pod pokličku" na implementaci metody vytvorAuto(), mohla by vypadat nějak takhle:

Auto vytvorAuto(String typAuta) {
switch (typAuta) {
        case "Skoda": return new Skoda();
        case "Audi": return new Audi();
    }
}

Syntaxe nemusí přesně odpovídat, nejsem na PC.

Odpovedať
Pokud spolu kód a komentář nekorespondují, budou patrně oba chybné
Avatar
Atrament
Člen
Avatar
Odpovedá na Ondřej Havlíček
Atrament:24.6.2023 13:23

U interface(rozhraní) je potřeba pochopit, že nejde o dědičnost v pravém slova smyslu, třída implementující nějaké rozhraní od toho rozhraní nic nedědí, ta třída se naopak zavazuje k tomu že sama implementuje metody specifikované v rozhraní. To je ten hlavní rozdíl oproti dědičnosti, kde naopak třída která dědí od nějaké jiné třídy, doopravdy dědí už existující funkčnost. U použití interface se správně tedy nemluví o dědičnosti ale o kompozici (skládání).

Dále je třeba pochopit, že v příkladu co uváděl Petr Štechmüller ta tovární metoda má sice návratovou hodnotu typu Auto, ale to nemusí být nutně zároveň typ instance, kterou vracíš pomocí return. Stačí právě, že bude typu, který implementuje interface Auto, takže to může být Skoda nebo Audi, tak jak je to v tom příkladu. V něm se vrací instance konkrétního typu Skoda nebo Audi podle vstupního parametru, ale my si ji uložíme do instance obecného typu Auto, protože je nám jedno jakého konkrétního typu je, my budeme pracovat pouze s metodama definovanýma v rozhraní Auto.

Dobré je to třeba k tomu, že můžeš všechny ty auta naházet do jedné kolekce List<Auto> a pracovat s nima hromadně. Nebo třeba k tomu, že když důsledně dodržuješ programování oproti interface, tak můžeš později konkrétní implementaci snadno změnit. Dobrý příklad je třeba zrovna ten List. List je jenom rozhraní, nejspíš bys použil konkrétní implementaci ArrayList:

List<Auto> auta = new ArrayList<>();

ale když by ses později rozhodl, že pro tvé účely je lepší LinkedList, stačilo by ti to změnit pouze na

List<Auto> auta = new LinkedList<>();

a ve zbytku aplikace bys nemusel měnit vůbec nic.

Avatar
Lukáš Raška:25.7.2023 21:28

Zatím mi není moc jasné, k čemu je to vlastně dobré. Metody mohu volat na třídě i na rozhraní Co získám tím, že třídě omezím volání metod pomocí interface?
Uvítal bych, kdyby tu bylo více rozepsané praktické využití.. ale snad se to dozvím dále...

Avatar
Vojtěch Šika:5.4.2024 9:37

Doporučuji se zde víc pobavit a vysvětlit co se rozumí pod pojem "Programovat proti rozhraní", pokud jsem to přehlédl opravte mě, nicméně mám pocit, že v kurzu tato problematika nebyla vysvětlena - přitom se tato znalost v navazujících dílech předpokládá... (Spring, Kolekce)....dost mě to zmátlo, respektive nutilo hledat jinde o co vlastně jde....zkušený programátor to bere jako samozřejmost.­...nicméně my začátečníci bohužel ne....Díky

Avatar
Jaromír Jurkovič:3.8.2024 12:51

Lekce je trochu zmatená a mohla by lépe vysvětlit praktický význam rozhraní.

Avatar
Lubomír Čipčala:28.12.2024 17:01

Takto jednoduše by mělo být vysvětleno vše, bohužel tomu tak v 70 % není, což je veliká škoda

Avatar
Vojtěch Kadlec:7. februára 10:55

Všechny dodatečné materiály v komentech pomohli, ale nevím jsetli tam úplně jsem. Po brouzdání po netu jsem si to ucelil, takto. Prosím o potvrzení.

1. Smyslem rozhraní je oddělit vrstvu komunikující ven vůči vrstvě implementující metody.
viz Továrna na auta zde v komentech. Kde na vstupu neřeším, co mi bude vráceno.

2. rozhraní mi dává možnost pracovat s dědičností na abstraktní úrovni, tak kde nedává symsl instance nebo chci kombici dědičnosti:

public interface Zvire {
        delejZvuky();
        dychej();
        }

public interface Ptaci extends Zvire {
        letej();
        }

public interface Plazi extends Zvire {
        plazSe();
        }

public interface Dravci {
        lov();
        }

public interface Bilozravci {
        pasSe();
        }

public class Pevci implements Ptaci, Bilozravci {
        // musím implementovat všechny metody
        delejZvuky();
        dychej();
        letej();
        pasSe();

public class Sykorka extends Pevci {
        //rozšiřuje vlastní atributy a metody
        }

public class PtakoJester implemets Ptaci, Plazi, Dravci {
        //zase implementuju metody

Za prvé neřešíme to přes třídy, protože dělat obecnou instatnci zvire nedáva logicky smysl.

Na druhou stranu jsem třídám dal hierarchii a ulehčil případné úpravy v budoucnu. Když doplním novou metodu do interface IDE mě vynadá, kde je potřeba implementovat.

A hlavně jsem s instancemi schopen pracovat na úrovni interface:

List<Zvire> zoo = new ArrayList<>;
zoo.add(konadra = new Sykorka() );
zoo.add(prisera = new Ptakojeste() );
System.out.println(zoo.size() );
for (Zvire zvire : zoo) {
        zvire.dychej();
        }
Avatar
Vojtěch Kadlec:7. februára 11:07

pomohli komentáře a další studium na webu, bez toho sem pochopil jak interface napsat, ale ne proč to udělat

Posledné komentáre sú na spodnej časti poslednej stránky.
Robíme čo je v našich silách, aby bola tunajšia diskusia čo najkvalitnejšia. Preto do nej tiež môžu prispievať len registrovaní členovia. Pre zapojenie sa do diskusie sa zaloguj. Ak ešte nemáš účet, zaregistruj sa, je to zadarmo.

Zobrazené 10 správy z 43.