<< Vytvárame funkčné triedy | Obsah | Polymorfizmus >>
Stalo sa, čo ste nepredpokladali. Vaša rodina bola nadšená vašim zoznamom DVD-čiek a chce od Vás, aby ste evidovali aj všetky filmy na videopáskach a v počítači. Samozrejme centrálne v jednom programe. Navyše im už nestačia informácie ako sa film volá, kto v ňom hrá, aké má žánre, dĺžku a hodnotenie. Chcú vedieť, kde film hľadať. Ale ono to je závislé na médiu, kde je film uložený:
Filmy na všetkých médiách majú nejaké spoločné dáta a funkcionalitu. Film na ľubovoľnom médiu si zachováva pôvodné dáta:
Rovnaké budú aj metódy spoločné pre filmy na všetkých médiách - mamZaner
, mamHerca
, retazecPreVypisFilmu
Rozdielne dáta sa týkajú identifikácie média, na ktorom sa film nachádza (očíslovanie, identifikácia počítača a cesty) a tiež niektoré doplňujúce údaje (začiatočná minúta, veľkosť súboru).
Rozdielne bude aj chovanie niektorých funkčných schopností (výpis umiestnenia filmu, uloženie do súboru, dodatočné informácie)
Dobrý programátor sa snaží každú metódu písať v celom programe iba na jednom mieste, v jednej jedinej kópii. Dôvod je zrejmý. Programátor pamätá na to, že každá metóda má veľkú šancu na svoju zmenu z rôznych dôvodov (prídu dáta s ktorými sa pred tým nerátalo, zákazník chce zmenu chovania metódy, Y2K,...) a v prípade jej zmeny to robí len na jednom mieste. Výhody sú tieto:
Z toho vyplýva, že nie je dobré, keby sme našu situáciu s troma druhmi médií pre filmy vyrobili 3 triedy (FilmNaDvd
, FilmNaPaske
, FilmVPocitaci
) a každá z nich by zisťovala napríklad prítomnosť herca vo filme svojou metódou s rovnakým telom. Mohlo by sa nám totiž stať, že zrazu niekto zahlási, že meno herca nestačí, lebo o hercoch chceme uchovávať aj národnosť, rasu, ocenenia a podobne. To by viedlo k tomu, že hercov nebudeme uchovávať ako pole String
-ov ale ako pole typu Herec[]
. Nasledovalo by trojnásobné prepisovanie typu inštančnej premennej herci
a trojnásobné prepisovanie metódy mamHerca
(a to náš program je ešte malý).
Využijeme dedičnosť, ktorú ste doteraz poznali pod názvom rozširovanie tried. Vyrobíme si triedu pre premenné a metódy, ktoré sú spoločné pre všetky typy médií. Následne vytvoríme triedy, ktoré rozširujú túto triedu o ďalšie vlastnosti. Táto spoločná trieda sa bude nazývať Film
a z nej rozšírené (oddedené) triedy sa budú volať FilmNaDvd
, FilmNaPaske
a FilmVPocitaci
. Tieto triedy budú môcť používať všetky metódy rodičovskej (rozširovanej) triedy Film
. Na podobné správanie sme už zvyknutí pri rozširovaní Turtle
alebo WinPane
.
Pre celkový obraz sa používa takzvaný triedový diagram, ktorý znázorňuje, ktorá trieda je rozšírením ktorej (resp. ktorá trieda dedí od ktorej).
Keď máme už tieto triedy naprogramované, môžeme prispúpiť k renovácii zoznamu filmov. Keďže máme médiá troch druhov zrejme by ste očakávali, že vytvoríme tri polia:
a potom pri výpise, ale aj pri všetkých ostatných metódach budeme používať 3 cykly:
Takýto prístup našťastie nie je potrebný, pretože platí, že premenná majúca typ nadradenej triedy (v našom prípade Film
) dokáže referencovať aj objekt, ktorý je inštanciou ľubovoľnej triedy, ktorá je jej potomkom (v našom prípade napr. FilmNaDvd
). Inými slovami z premennej typu Film
vieme referencovať objekty typu Film
, FilmNaDvd
, FilmNaPaske
alebo FilmVPocitaci
:
Cez premenné matrix
a matrix2
však môžeme volať iba tie metódy, ktoré sú definované v triede Film
alebo jej predkoch. Nasledujúce teda nie je možné:
Teda od premennej typu Film
môžeme požadovať iba to, čo umožňuje trieda Film
. Keďže pri dedičnosti platí, že triedy vedia všetko to, čo zdedili od predkov, tak aj objekty tried FilmNaDvd
, FilmNaPaske
alebo FilmVPocitaci
vedia všetko to, čo by sme mohli požadovať od Film
-u.
Treba si dať pozor na to, že opačné pravidlo neplatí, t.j. z premennej, ktorá je typu potomka (napr. FilmNaDvd
) nevieme referencovať objekt typu predka (napr. Film
). Je to logické keď si uvedomíte, že cez premennú typu FilmNaDvd
očakávame možnosť volania ľubovoľnej metódy triedy FilmNaDvd
, a to objekt triedy Film
poskytnúť nevie.
Budeme si teda uchovávať iba jedno pole filmov a môžeme z neho referencovať všetky typy médií. Výpis filmov už teda bude iba cez jedno pole.