Neustále narážím na testové otázky ve kterých se ptají na programátorské základy, jednou z nich je triviální dotaz na rozdíl mezi abstraktní třídou a rozhraním. Tak tedy:
Abstraktní třída
Abstraktní třída je obyčejná třída, která jenom nemá definované některé metody; předpokládá se, že nějaká jiná třída z ní bude dědit a tyto metody si doplní podle potřeby.
Je to hybrid mezi rozhraním a klasickou třídou. Od klasické třídy má schopnost implementovat vlastnosti (proměnné) a metody, které se na všech odvozených třídách budou vykonávat stejně. Od rozhraní zase získala možnost obsahovat prázdné abstraktní metody, které si každá odvozená podtřída musí naimplementovat sama. S těmito výhodami má abstraktní třída i pár omezení, a to že jedna podtřída nemůže zdědit víc abstraktních tříd a od rozhraní přebírá omezení, že nemůže vytvořit samostatnou instanci (operátorem new).
Rozhraní
Interface je seznam metod, které by měla třída podporovat, aby plnila nějaký účel. Jestliže se třída hlásí k tomu, že podporuje daný interface, musí definovat všechny metody, které předepisuje interface.
Interface předepisuje třídě, která od ní bude odvozena, jaké metody (případně properties) musí implementovat. Odvozený objekt může implementovat i další metody. Interface nedefinuje žádné proměnné ani neobsahuje naimplementované metody (pouze jejich hlavičky). Přitom třída může implementovat libovolný počet rozhraní (na rozdíl od dědičnosti).
Krátce
Abstraktní třída
- může obsahovat instanční proměnné
- může obsahovat konkrétní metody i metody bez implementace
- lze rozšiřovat pouze jednu třídu
Rozhraní
- nesmí obsahovat proměnné
- všechny metody jsou bez implementace
- do jedné třídy lze implementovat více rozhraní
Tolik jenom k tomuto věčnému akademickému tématu.
Dokázal bys prosím vysvětlit, k čemu slouží defaultní metody (které nemají tělo abstraktní metody prázdné) v rozhraní? V Javě od verze 8.
OdpovědětVymazatDefinují povinné metody, které musí potomek mít definované.
Vymazattzn.: Pokud v abstraktní třídě/rozhraní nadefinuji metodu:
"public setX(int x) {
} "
tak každý potomek musí obsahovat metodu:
"public setX(int x) {
/** nějaké tělo metody
a předpokládá se, že každý potomek bude mít jiné instrukce v této metodě
*/
}"