Seminář 3
Obsah semináře
- OOP v Javě II:
- polymorfismus
- rozhraní
OOP podruhé
Dnes nás čeká:
- Principy:
- polymorfismus,
- zapouzdření.
- Prvky jazyka:
- modifikátory přístupu
private
,protected
apublic
, - rozhraní (interface),
- klíčová slova
implements
ainstanceof
Narazíme i na:
- Klíčové slovo
default
. Implementace funkcionality v rozhraní.
Polymorfismus
- Na objekt lze nahlížet z více úhlů pohledu - může být instancí více různých tříd a rozhraní (s omezeními, vizte dále). Např. jeden člověk může být úředník, manžel i skaut - a dle aktuální situace tedy mít různé vlastnosti a možnosti.
- Více tříd může mít stejné metody. Např. metodu
toString()
mají všechny objekty (všechny instance všech tříd). - Metoda jednoho názvu může mít více verzí s různými seznamy argumentů (už jste viděli).
Zapouzdření
- Vnitřní a vnější rozhraní objektu
- Viditelnost dané entity ovlivněna modifikátory přístupu:
private
- k této entitě má přístup jen objekt samotnýprotected
- k této entitě má přístup cokoliv v rámci stejného balíčku a případní potomci mimo balíčekpublic
- k této entitě má přístup kdokoliv (veřejná API balíčku)- default - k této entitě má přístup cokoliv v rámci stejného balíčku. Výchozí modifikátor, nepíše se.
- Veřejnou API mohou dále (výrazně) ovlivnit tzv. moduly. To je ale mimo rozsah tohoto semináře.
- Pozor je to jinak než v C#.
- Speciální metody pro kontrolovaný přístup k atributům:
- čtení - getter
- zápis - setter
- může jich být více (polymorfismus) anebo taky nemusí být žádný
- v Javě typické pojmenování
getXXX
asetXXX
(není vynucováno IDE, ale má to své důvody)
- (ukázka): Máme třídu
BetterCar
(vizte ukázku níže), podobnou té z minula. Upravíme ji tak, aby:- Rychlost šla nastavovat jen v rozsahu min-max rychlosti auta.
- Změna posádky byla možná, jen když auto stojí.
- SPZ nešla po vytvoření změnit vůbec.
- Všimněte si, že v kódu třídy
BetterCar
můžu stále dělat, co chci - je má zodpovědnost, aby to dávalo smysl. Ale uživatel této třídy už může používat jen mnou nadefinované veřejné rozhraní, a tedy nemůže například vysadit posádku ve 100 Km/h.
Rozhraní (interface)
- Konstrukt jazyka. Pozor, souběh pojmů - něco jiného než vnitřní a vnější rozhraní objektu.
- Umožňuje vynutit, aby nějaké třídy implementovaly nějaké metody (kontrakt). Typicky nějaká abstraktní vlastnost, kterou mohou mít různé spolu vůbec nesouvisející třídy.
- Příklady rozhraní (v dokumentaci mimo jiné vidíte, které třídy standardní knihovny dané rozhraní implementují):
- Comparable zajišťuje, že třída implementuje vše potřebné k porovnávání jejich instancí.
- Closeable zajišťuje, že třída má metodu
close()
, která uvolňuje nějaké držené zdroje. - AutoCloseable zajišťuje, že vytvářeny a rušeny v tzv. try-with-resources bloku (uvidíme později). Zjednodušeně jde o automatické uzavírání již nepotřebných zdrojů (soubory, sockety, …).
- Obvykle autor rozhraní není schopen říct, jak to jednotlivé konkrétní třídy budou dělat. Konkrétní implementace těchto metod může být úplně odlišná pro různé třídy.
- Rozhraní v Javě nemůže obsahovat žádné atributy kromě konstant. Veřejné třídní (static) metody mohou mít implementaci, veřejné instanční metody
také, ale musí být označeny klíčovým slovem
default
. Soukromé metody mohou mít implementaci. - Každá třída může implementovat více rozhraní. Klíčové slovo
implements
. - Instance rozhraní je každá instance každé třídy, která toto rozhraní implementuje.
- Jak zjistit, jestli daný objekt implementuje dané rozhraní? Klíčové slovo
instanceof
. (ukázka):
Dále (bude jasnější příště):
- Rozhraní může dědit z jiného rozhraní (i více) pomocí
extends
. (Dědičnost příště.) - Rozhraní nemůže být
final
, ale podobně jako sealed třídy existují od Java 17 i sealed rozhraní.
Zdroje
Úkoly
- Implementujte rozhraní
Countable
s jedinou metodouint count()
a rozhraníMeasurable
s jedinou metodoudouble length()
- Implementujte třídy pro následující data:
- letopočet - den, měsíc, rok (úprava: nemusíte řešit platnost data)
- konečná množina přirozených čísel - alespoň s možností přidávat a odebírat prvky (pozor na duplicity)
- interval reálných čísel
- úsečka v rovině
- seznam přirozených čísel - alespoň s možností přidávat a odebírat prvky
- U každé třídy z bodu 2 popřemýšlejte, které z rozhraní z bodu 1 by mohla implementovat. Kde to dává smysl, rozhraní implementujte.
- Navrhněte a implementujte rozhraní pro obecnou kolekci čísel typu
int
. Tj. vymyslete, jaké vlastnosti a možnosti by měla mít každá kolekce “celých čísel” (např. množina, seznam, pole, strom, …). - Navrhněte a implementujte třídu pro spojový seznam, která bude implementovat rozhraní z předchozího bodu.
- Výsledek odevzdejte emailem s předmětem jj1-03 na tomas.urbanec@upol.cz do 10.10.2023, 14:59 CEST. Odevzdávejte pouze zdrojové kódy, nikoliv celé projekty vygenerované IDE.