Java: Abstraktní třídy, dědičnost a rozhraní
Z MiS
(Rozdíly mezi verzemi)
(→Rozhraní: Přidán popis rozhraní.) |
(Přidáno srovnání konstruktů.) |
||
Řádka 54: | Řádka 54: | ||
* Klíčové slovo <code>abstract</code>. | * Klíčové slovo <code>abstract</code>. | ||
* Těla některých metod nejsou uvedena. | * Těla některých metod nejsou uvedena. | ||
+ | |||
+ | |||
+ | == Srovnání konceptů == | ||
+ | ; Dědičnost | ||
+ | * Používáme tehdy, kdy potomek přebírá ''všechny'' vlastnosti předka (a případně přidává něco dalšího). | ||
+ | * Třída může mít ''jen jednoho'' předka. | ||
+ | ; Rozhraní | ||
+ | * Pouze předepisuje, jaké metody má třída mít. | ||
+ | * Nemůžeme z rozhraní převzít hotový kód. | ||
+ | * Nelze vytvořit instanci rozhraní (nelze volat <code>new Rozhrani()</code>). | ||
+ | * Můžeme implementovat kolik rozhraní chceme. | ||
+ | * Je užitečné, když každá třída má na společnou zprávu reagovat jinak. | ||
+ | ; Abstraktní třída | ||
+ | * Je jakýmsi mezistupněm, kdy přebíráme kód jen některých metod. | ||
+ | * Nelze vytvářet instance abstraktní třídy. | ||
Verze z 7. 4. 2017, 09:38
Obsah |
Dědičnost
- Klíčové slovo
extends
. - Třída může mít pouze jednu rodičovskou třídu!
- Potomek „dědí“ všechny vlastnosti předka.
- Potomek může kdykoli nahradit předka. Takže pokud máme proměnnou datového typu
Predek
, můžeme do ní uložit instanci třídyPotomek
. Opačně to však nejde!
- Příklad
public class Kamion { int nosnost; ... public int getNosnost() { return this.nosnost; } ... } public class KamionSPrivesem extends Kamion { Prives prives; ... public int getNosnost() { return this.getHodnota()+this.prives.getHodnota(); } ... }
Rozhraní
- Klíčové slovo
implements
. - Může mít pouze hlavičky metod a veřejné konstantní atributy.
- Implementací rozhraní garantujeme, že naše třída má určité metody.
- Zajišťujeme například to, aby objekty různých tříd šly umístit do kontejneru.
- Deklarace rozhraní
public interface Zasahnutelne { public void zasah(Strela s); // Neříkáme, jak se má objekt chovat. // Jen vyžadujeme, že bude mít tuto metodu. }
- Třída, která implementuje rozhraní
public class Prisera { ... ... Může mít různé metody a atributy, ale musí mít metodu zasah(...)!!! ... public void zasah(Strela s) { // Popíšeme, jak se má reagovat na zprávu/metodu zasah(...). this.getWorld().removeObject(this); }
Abstraktní třída
- Klíčové slovo
abstract
. - Těla některých metod nejsou uvedena.
Srovnání konceptů
- Dědičnost
- Používáme tehdy, kdy potomek přebírá všechny vlastnosti předka (a případně přidává něco dalšího).
- Třída může mít jen jednoho předka.
- Rozhraní
- Pouze předepisuje, jaké metody má třída mít.
- Nemůžeme z rozhraní převzít hotový kód.
- Nelze vytvořit instanci rozhraní (nelze volat
new Rozhrani()
). - Můžeme implementovat kolik rozhraní chceme.
- Je užitečné, když každá třída má na společnou zprávu reagovat jinak.
- Abstraktní třída
- Je jakýmsi mezistupněm, kdy přebíráme kód jen některých metod.
- Nelze vytvářet instance abstraktní třídy.
Odkaz na předka — super
- Jsou situace, kdy potřebujeme změnit chování některé metody předka v potomkovi. Mluvíme o překrývání metod.
- Pokud potřebujeme v potomkovi přesto použít metodu předka, použijeme k tomu klíčové slovo
super
. - Klíčovým slovem
super
lze také zavolat konstruktor předka.
Přetypování
- Potomek může vždy zastoupit předka. Do proměnné datového typu předka tedy můžeme uložit instanci třídy potomka.
- Jsou ale situace, kdy potřebujeme k takto uloženému potomkovi znovu přistupovat jako k potomkovi včetně všech jeho metod a atributů.
- V tom případě musíme použít přetypování.
- Přetypování zapíšeme tak, že do závorky před výraz, který vrací takto uloženého potomka, zapíšeme název třídy předka.
- Příklady přetypování
- Greenfoot a detekce kolize s konkrétním typem aktéra
Prekazka prekazka = (Prekazka) this.getOneIntersectingObject(Prekazka.class); if (prekazka != null) { int prekazka.getPruhlednost(); ... }
- GUI pomocí knihovny Swing — zjištění zdroje události
public void actionPerformed(ActionEvent event) { Button zdroj = (Button) event.getSource(); zdroj.getTitle(); ... }
Pozor, musíme si být stoprocentně jisti, že objekt, který je uložen v proměnné datového typu
Predek
je ve skutečnosti opravdu datového typu Potomek
. Pokud by nebyl, běh programu by skončil výjimečný stavem a aplikace by havarovala.