Seminář 4
Obsah semináře
- OOP v Javě III:
- Dědičnost
- Statické (třídní) atributy a metody
- Záznamy (record)
Dnes nás čeká:
- Principy:
- dědičnost
- Prvky jazyka:
- klíčová slova
extends
ainstanceof
- záznamy
record
- klíčová slova
Narazíme i na:
- Anotace
@Override
, - Klíčové slovo
final
- konstanty, omezení dědičnosti.
Dědičnost
Pravidlo … is a … → dědičnost
Pravidlo … has a … → kompozice
Příklad: Už jsme implementovali třídu pro auta. Představme si, že máme podobnou, která bude základem pro popis nějakého dopravního systému.
Co kdybychom do něj ted chtěli přidat i motorky, kola, vlaky, …?- Třídy
Motorbike
,Bicycle
,Train
,Bus
,Tram
, … - Mají toho mnoho společného, abstrahujme tedy společné do třídy
Vehicle
- dopravní prostředek. Všechny třídy výše pak budou dědit zVehicle
a jen doplní svá specifika.
- Třídy
V kódu potomka se dá přistupovat k metodám a (přístupným) atributům předka přes klíčové slovo
super
.Třída může překrýt implementaci metody předka. Pokud jde o instančí metodu, pak je přepsána a k metodě předka už se přes daný objekt (mimo kód potomka a
super
) nedostaneme. Přepis (čehokoliv z předka) se označuje anotací@Override
.Dědičnost se dá omezit
- Označíme-li třídu klíčovým slovem
final
, tak z ní nepůjde dále dědit. - Označíme-li metodu klíčovým slovem
final
, tak nepůjde překrýt. - Od Java 17 máme sealed třídy. Sofistikovanější mechanizmus pro omezení dědičnosti (lze omezit, kdo může dědit z naší třídy).
- Označíme-li třídu klíčovým slovem
Každá třída může dědit z nejvýše jedné třídy. Klíčové slovo
extends
.
(ukázka)
Statické atributy a metody
- Atribut či metoda v dané třídě může být uvozen kíčovým slovem
static
(např.public static int age;
) - Takový atribut/metoda je příslušný/á celé třídě, nikoliv jen konkrétní instanci.
- Lze k němu/ní přistupovat i bez existující instance.
- Už známe
public static void main(String[] args)
.
(ukázka)
Záznamy (Record)
- Popis v release notes.
- Slouží k jednoduché agregaci souvisejících dat.
- Je to vlastně omezená třída s jednodušším zápisem a konstantním obsahem.
- Dodáme název a seznam atributů, zbytek (gettery, konstruktor, toString(), equals(…), hasCode(…)) doděla překladač.
- Vše dodělané překladačem můžeme přepsat (konstruktor i ve zkrácené formě), ale pak za to ručíme sami.
- Můžeme přidat další libovolný
static
obsah a instanční metody (avšak ne instanční atributy). - Všechny třídní atributy budou vždy
final
, tedy nemá smysl uvažovat settery. - Každý record je implicitně
final class
, tedy z nich nelze dále dědit. - Lze s nimi pracovat lokálně.
- Další vlastnosti zatím mimo naše možnosti - pro zájemce odkaz výše.
(ukázka)
Kódy z hodiny
Úkoly
- Nejprve si pročtěte celé zadání a úkol si promyslete.
- Jde o vhodné použití všech principů a prvků OOP z tohoto a minulých seminářů: polymorfismus, zapouzdření, dědičnost, kompozice, třídy, záznamy, rozhraní, …
Kde co použít, určete sami. - Výraz něco nazvaného
XXX
znamená, že máte sami zvolit, jestli se jedná o třídu, zaznam, rozhraní, … - Implementujete knihovnu pro rovinné útvary, mějte to na paměti při návrhu hierarchi tříd, rozhraní a záznamů.
- EDIT: Pro jednoduchost vzdálenosti berte vždy ke středu daného útvaru (kruhu, čtverce, úsečky, …).
- Implementujte něco nazvaného
Point
pro bod v rovině se dvěma souřadnicemi. Po vytvoření bodu jeho souřadnice již nepůjdou měnit.
- Implementujte metodu
double distance(Point p)
vracející vzdálenost bodu a dalšího bodup
.
- Implementujte něco nazvaného
- Implementujte něco nazvaného
LineSegment
pro úsečku v rovině.
- Implementujte tyto metody:
double distance(Point p)
vracející vzdálenost úsečky a bodup
,double length()
vracející délku úsečky.
- Implementujte něco nazvaného
- Implementujte něco nazvaného
Rectangle
představující obdelník, který má strany rovnoběžné s osami X a Y.
- Implememntujte dva konstruktory:
- pomocí dvou vrcholů (přes uhlopříčku),
- pomocí levého dolního vrcholu, výšky a šířky.
- Implementujte tyto metody:
double getArea()
vracející obsah obdelníku,double distance(Point p)
vracející vzdálenost od daného bodu, tj. minimální vzdálenost bodu k některé ze stran obdelníku.
- Implementujte něco nazvaného
- Implementujte něco nazvaného
Square
představující čtverec, který má strany rovnoběžné s osami X a Y.
- Implememntujte dva konstruktory:
- pomocí dvou vrcholů (přes uhlopříčku),
- pomocí levého dolního vrcholu a strany.
- Implementujte tyto metody:
double getArea()
vracející obsah čtvercedouble distance(Point p)
vracející vzdálenost od daného bodu, tj. minimální vzdálenost bodu k některé ze stran čtverce.
- Implementujte něco nazvaného
- Implementujte něco nazvaného
Circle
pro kruh/kružnici,
- Implementujte konsturktor pomocí středu a poloměru.
- Implementujte tyto metody:
double getArea()
vracející obsah kruhu,double distance(Point p)
vracející vzdálenost od daného bodu, tj. minimální vzdálenost bodu k libovolnému bodu ležícímu na kružnici.
- Implementujte něco nazvaného
Má-li smysl přidat nějakou třídy, záznam či rozhraní k zpřehlednění/zkvalitnění kódu, udělejte to.
Výsledek odevzdejte emailem s předmětem jj1-04 na tomas.urbanec@upol.cz do 24.10.2023, 14:59 CEST. Odevzdávejte pouze zdrojové kódy, nikoliv celé projekty vygenerované IDE.
Nepovinné úkoly:
- Podívejte se na zajímavý problém. Jak to souvisí s vaším řešením úkolu?