Polymorfizmus
Štrnásta prednáška
Stiahnuť PDF · 3,9 MBPreber si túto poznámku so svojou AI
Skopíruj pripravený podklad a vlož ho do ChatGPT, Claude alebo inej AI — bude ťa učiť alebo skúšať len z tejto poznámky.
Náhľad poznámky
Polymorfizmus
Informatika 2
Pojmy zavedené v 2. prednáške(1)
• implementačná závislosť – minimálna
• súdržnosť – maximálna
• zodpovednosť – jedna jasne definovaná
– miery dobrého návrhu tried
• duplicita kódu – súdržnosť
• priamy prístup k atribútom – závislosť,
zodpovednosť
Informatika 2
1
Pojmy zavedené v 2. prednáške(2)
• refaktoring
• zmena kódu bez zmeny jeho funkcie
• úpravy pre zlepšenie miery závislosti, súdržnosti a
zodpovednosti
• overenie korektnosti refaktoringu – regresné
testovanie
Informatika 2
2
Pojmy zavedené v 2. prednáške(3)
• HashMap – kontejner
• neusporiadaná množina usporiadaných dvojíc
(kľúč, hodnota)
• kľúč – unikátny
• poskytuje hodnoty určené kľúčom
• prechádzanie kontejnerom – cyklus for each
Informatika 2
3
Cieľ prednášky
• polymorfizmus
• interface
• príklad: hra „World of FRI“
Informatika 2
6
„World of FRI“
• ľubovoľné smery
• bez implementačnej závislosti
• výsledok refaktoringu
Informatika 2
7
Nová úloha
• pridať nový príkaz „ukaz“
• do terminálového okna sa vypíše informácia o
miestnosti, v ktorej sa hráč nachádza
• kde sa pracuje s príkazmi?
Informatika 2
8
WoF
– diagram tried
Informatika 2
9
Kde sa pracuje s príkazmi?
Informatika 2
10
• trieda NazvyPrikazov
– udržiava zoznam názvov príkazov
– odpovedá na otázku „jePrikaz“
• trieda Parser
– načítava text príkazu z okna terminálu
– rozkladá ich na dvojice príkaz, parameter
– požiada o inštanciu triedu Prikaz
Kde sa pracuje s príkazmi?
• trieda Prikaz
– uchováva názov príkazu a prípadný parameter
• trieda Hra
– vykonáva príkazy
Informatika 2
11
Úlohy triedy Hra
1. Riadenie priebehu hry
2. Udržiavanie informácii o hráčovi (aktuálna
miestnosť)
3. Vytváranie miestností – „mapa hry“
4. Vykonávanie príkazov
• veľa úloh – refaktoring
Informatika 2
12
Refaktoring triedy Hra(1)
• informácie o hráčovi do samostatnej triedy
• vytvorenie mapy hry do samostatnej triedy
Informatika 2
13
Refaktoring triedy Hra(1)
Informatika 2
14
Trieda MapaHry
Informatika 2
15
Trieda Hrac
Informatika 2
16
Vykonávanie príkazov
• Hra – metóda vykonajPrikaz
→
• možnosti:
– trieda Prikaz
– nová trieda
• vykonávanie príkazu –> práca s dátami príkazu –>
zodpovednosť triedy Prikaz
Informatika 2
17
Metóda vykonajPrikaz v triede Hra(1)
private boolean vykonajPrikaz(Prikaz paPrikaz)
{
boolean jeKoniec = false;
if (paPrikaz.jeNeznamy()) {
System.out.println("Nerozumiem");
return false;
}
...
Informatika 2
18
Metóda vykonajPrikaz v triede Hra(2)
...
String nazovPrikazu = paPrikaz.dajNazov();
if (nazovPrikazu.equals("pomoc")) {
vypisNapovedu();
} else if (nazovPrikazu.equals("chod")) {
chodDoMiestnosti(paPrikaz);
} else if (nazovPrikazu.equals("ukonci")) {
jeKoniec = ukonciHru(paPrikaz);
}
return jeKoniec;
}
Informatika 2
19
Závyslosti metódy vykonajPrikaz
• metóda vykonajPrikaz v hre je závislá od metód:
– vypisNapovedu
– chodDoMiestnosti
– ukonciHru
• tieto metódy treba preniesť tiež
Informatika 2
20
Sprístupnenie hráča v triede Prikaz
• v hre je hráč atributom aHrac
• v príkaze ako parameter metódy vykonaj
• v hre je príkaz parametrom metódy vykonajPrikaz
• v príkaze sú vlastnosti príkazu priamo prístupné
Informatika 2
21
Metóda vykonaj v triede Prikaz(1)
public boolean vykonaj (Hrac paHrac)
{
boolean jeKoniec = false;
if(jeNeznamy()) {
System.out.println("Nerozumiem");
return false;
}
...
Informatika 2
22
Metóda vykonaj v triede Prikaz(2)
...
String nazovPrikazu = dajNazov();
if (nazovPrikazu.equals("pomoc")) {
vypisNapovedu();
} else if (nazovPrikazu.equals("chod")) {
chodDoMiestnosti(paHrac);
} else if (nazovPrikazu.equals("ukonci")) {
jeKoniec = ukonciHru();
}
return jeKoniec;
}
Informatika 2
23
Kde sa pracuje s príkazmi?
• trieda Prikaz
– uchováva názov príkazu a prípadný parameter
– vykonáva príkazy
• trieda Hra
– žiada príkaz o vykonanie (ako celok)
Informatika 2
24
Úlohy triedy Hra
1. Riadenie priebehu hry
• refaktoring dokončený
• rozšírenie funkcií hry – príkaz ukaz
Informatika 2
25
Nový príkaz „ukaz“
• dve rôzne riešenia
– nový príkaz do triedy Prikaz
– nové triedy – vykonanie každého príkazu
Informatika 2
26
Nový príkaz do triedy Prikaz
• pozitívum riešenia
– mechanické rozšírenie súčasného stavu
• negatíva riešenia
– zväčší sa veľkosť triedy
– zhoršuje sa udržiavateľnosť
Informatika 2
27
Triedy na vykonávanie
• riešenie – vykonávanie každého príkazu (podľa
názvu) v samostatnej triede
• pozitívum riešenia
– každá trieda má jasne určenú zodpovednosť
– pridanie príkazov nemá vplyv na už zavedené
• negatívum riešenia
– väčší počet tried
Informatika 2
28
Refaktoring – triedy vykonavacov
• VykonavacChod
– void vykonaj(Hrac paHrac, String paParameter)
• VykonavacPomoc
– void vykonaj()
• VykonavacUkonci
– boolean vykonaj(String paParameter)
Informatika 2
29
Model tried „WoF“
Informatika 2
30
Ukážka novej triedy
public class VykonavacPomoc
{
public void vykonaj()
{
System.out.println("Zabludil si. Si sam. Tulas sa po fakulte.");
System.out.println();
System.out.println("Mozes pouzit tieto prikazy:");
System.out.println(" chod ukonci pomoc");
}
}
Informatika 2
31
32
Informatika 2
Metóda vykonaj v triede Prikaz
if (nazovPrikazu.equals("pomoc")) {
vypisNapovedu();
} else if (nazovPrikazu.equals("chod")) {
...
if (nazovPrikazu.equals("pomoc")) {
VykonavacPomoc vykonavac;
vykonavac = new VykonavacPomoc();
vykonavac.vykonaj();
} else if (nazovPrikazu.equals("chod")) {
...
Metóda vykonaj v triede Prikaz – cieľ
public boolean vykonajPrikaz(Hrac paHrac)
{
if (jeNeznamy()) {
System.out.println("Nerozumiem");
return false;
}
Vykonavac vykonavac;
vykonavac = aPrikazy.dajVykonavac(aNazov);
return vykonavac.vykonaj(paHrac, aParameter);
}
Informatika 2
33
Polymorfizmus(1)
• riešenie možné vďaka polymorfizmu
• polymorfizmus:
využitie určitej špeciálnej situácie, keď dva rôzne
objekty môžu prijať tú istú správu a pritom každý
z nich reaguje inak – použije inú metódu
Informatika 2
34
Polymorfizmus(1)
• odosielateľ správy sa nestará o typ adresáta
– zjednodušenie na strane odosielateľa
• postačuje, že adresát je schopný správu prijať
– má správu v rozhraní
• každý adresát použije svoju metódu
Informatika 2
35
Polymorfizmus - druhy
• preťažovanie – metódy a konštruktory s rôznym
typom alebo počtom parametrov
• pretypovávanie – autoboxing
• parametrický – generické triedy
Informatika 2
36
polymorfizmus
ad-hoc
univerzálny
preťažovanie
parametrický
pretypovanie
inkluzívny
Protokol: správa → metóda
• jedna správa
• rôzne metódy
Informatika 2
37
vykonavac.vykonaj()
{VykonavacPomoc.} vykonaj
{VykonavacChod.} vykonaj
{VykonavacUkonci.} vykonaj
odosielateľ
adresát
{alebo}
Prostriedky jazyka Java
• správa v rozhraní – podmienka pre jej poslanie
• interface
– explicitná definícia zoznamu správ v rozhraní
– definuje typ objektových premenných
• trieda implementuje interface
– zaručuje, že má implementované všetky metódy pre
správy uvedené v interface
– inštancie sú schopné chovať sa polymorfne - inkluzívny
Informatika 2
38
Aplikácia interface do hry
Informatika 2
39
Interface IVykonavac
• kľúčové slovo interface
• správy bez modifikátora prístupu ukončené ;
• vždy public
Informatika 2
40
public interface IVykonavac
{
boolean vykonaj(Hrac paHrac, String paParam);
}
Implementácia rozhrania
• explicitné uvedenie inteface v hlavičke triedy
• ľubovoľný počet implementovaných interface
• metódy pre všetky správy z interface
– musia byť verejné
– správy sa musia presne zhodovať
Informatika 2
41
Java – implementácia rozhrania
public class VykonavacPomoc implements IVykonavac
{
public boolean vykonaj(Hrac paHrac, String paParam)
{
System.out.println("Zabludil si. Si sam.");
System.out.println();
System.out.println("Mozes pouzit tieto prikazy:");
System.out.println(" chod ukonci pomoc");
return false;
}
}
Informatika 2
42
Interface v UML(1)
• obdĺžnik – ako trieda
• stereotyp «interface» nad menom
• len správy inštancii
Informatika 2
43
Interface v UML(2)
Informatika 2
44
Poslanie správy prem. typu interface
IVykonavac vykonavac;
vykonavac = aPrikazy.dajVykonavac(aNazov);
vykonavac.vykonaj(paHrac, aParameter);
Informatika 2
45
Statický kontra dynamický typ(1)
• statický typ
– uvedený v definícii objektovej premennej
– určuje sa pri preklade
– určuje množinu správ, ktoré je možno poslať (iné nie)
• dynamický typ
– skutočný typ objektu referencovaného premennou
– určuje sa za behu pri priradení hodnoty premennej
– určuje chovanie objektu, reakcie na správy
Informatika 2
46
47
Informatika 2
Statický kontra dynamický typ(2)
IVykonavac vykonavac;
vykonavac = aPrikazy.dajVykonavac(aNazov);
vykonavac.vykonaj(paHrac, aParameter);
statický typ
dynamický typ
nevieme odvodiť z príkazu
môže byť
VykonavacUkonci, VykonavacPomoc, VykonavacChod
48
Informatika 2
Spracovanie správy pri polymorfizme(1)
vykonavac.vykonaj(paHrac, aParameter);
VykonavacPomoc
49
Informatika 2
Spracovanie správy pri polymorfizme(1)
vykonavac.vykonaj(paHrac, aParameter);
VykonavacUkonci
Statický kontra dynamický typ
• príkaz bol rovnaký
• statický typ je rovnaký
• vykonávajú sa rôzne metódy
Informatika 2
50
Metóda dajVykonavac v NazvyPrikazov
public IVykonavac dajVykonavac(String paNazov)
{
if (paNazov.equals("pomoc")) {
return new VykonavacPomoc();
} else if (paNazov.equals("chod")) {
return new VykonavacChod();
} else if (paNazov.equals("ukonci")) {
return new VykonavacUkonci();
}
return null;
}
Informatika 2
51
Typová kompatibilita a interface
• inštancia je typovo kompatibilná s interface ak jej
trieda implementuje daný interface
• hodnota null je typovo kompatibilná so všetkými
interface
Informatika 2
52
Typová kompatibilita v dajVykonavac(1)
public IVykonavac dajVykonavac(String paNazov)
{
if (paNazov.equals("pomoc")) {
return new VykonavacPomoc();
} else if (paNazov.equals("chod")) {
return new VykonavacChod();
} else if (paNazov.equals("ukonci")) {
return new VykonavacUkonci();
}
return null;
}
Informatika 2
53
class VykonavacUkonci implements IVykonavac
Typová kompatibilita v dajVykonavac(2)
public IVykonavac dajVykonavac(String paNazov)
{
if (paNazov.equals("pomoc")) {
return new VykonavacPomoc();
} else if (paNazov.equals("chod")) {
return new VykonavacChod();
} else if (paNazov.equals("ukonci")) {
return new VykonavacUkonci();
}
return null;
}
Informatika 2
54
Zjednodušenie pomocou HashMap
• inštancie vykonávačov nemajú atribúty
• => nemenia svoj stav
• => všetky inštancie budú mať rovnaký stav
• => možno ich predpripraviť do zoznamu
Informatika 2
55
Trieda NazvyPrikazov s HashMap(1)
private final HashMap<String, IVykonavac> aVykonavace;
public NazvyPrikazov()
{
aVykonavace = new HashMap<String, IVykonavac>();
aVykonavace.put("pomoc", new VykonavacPomoc());
aVykonavace.put("chod", new VykonavacChod());
aVykonavace.put("ukonci", new VykonavacUkonci());
}
Informatika 2
56
Trieda NazvyPrikazov s HashMap(1)
public boolean jePrikaz(String paNazov)
{
return aVykonavace.containsKey(paNazov);
}
public IVykonavac dajVykonavac(String paNazov)
{
return aVykonavace.get(paNazov);
}
Informatika 2
57
Nový príkaz ukaz
• refaktoring
• jednoduché pridávanie príkazov
1. nová trieda – vykonávač
2. zaradenie inštancie do HashMap
Informatika 2
58
Pridanie nového príkazu – vykonávač
public class VykonavacUkaz implements IVykonavac
{
public boolean vykonaj(Hrac paHrac, String paPar)
{
Miestnost akt = paHrac.dajAktualnuMiestnost();
System.out.println(akt.dajUplnyPopis());
return false;
}
}
Informatika 2
59
Pridanie nového príkazu – HashMap
aVykonavace = new HashMap<String, IVykonavac>();
aVykonavace.put("pomoc", new VykonavacPomoc());
aVykonavace.put("chod", new VykonavacChod());
aVykonavace.put("ukonci", new VykonavacUkonci());
aVykonavace.put("ukaz", new VykonavacUkaz());
Informatika 2
60
Konečný stav
Informatika 2
61
Vďaka za pozornosť
Automaticky vygenerovaný textový náhľad. Pre plné formátovanie si stiahnite súbor.
nechodím na prednášky