Polymofizmus-pretypovanie
Pätnásta prednáška
Stiahnuť PDF · 5,7 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 II
Informatika 2
Pojmy zavedené v 3. prednáške(1)
• polymorfizmus
• polymorfizmus a protokol
• druhy polymorfizmu
Informatika 2
1
Pojmy zavedené v 3. prednáške(2)
• interface
• interface - Java
• interface - UML
Informatika 2
2
Pojmy zavedené v 3. prednáške(3)
• typová kompatibilita - interface
• statický a dynamický typ
Informatika 2
3
4
Informatika 2
Rozhranie – vonkajší pohľad
odosielateľ
adresát
správa
5
Informatika 2
Implementácia – vnútorný pohľad
adresát
metóda
protokol
6
Informatika 2
Jazyk – vonkajší pohľad
odosielateľ
adresát
správa
Trieda
správa
typ premennej
7
Informatika 2
Jazyk – vnútorný pohľad
odosielateľ
adresát
správa
Trieda
metóda
typ inštancie
protokol
8
Informatika 2
Polymorfizmus – vonkajší pohľad
odosielateľ
adresát
správa
Interface
správa
typ premennej
9
Informatika 2
Polymorfizmus – vonkajší pohľad
odosielateľ
adresát
správa
Interface
správa
typ premennej
Trieda
metóda
typ inštancie
protokol
statický typ
dynamický typ
Cieľ prednášky
• polymorfizmu – pokračovanie
– pretypovanie – implicitné, explicitné
• testovanie – pokračovanie
– testy tried pre komunikáciu s používateľom
• príklad: hra „World of FRI“
– predmety
Informatika 2
10
Súčastný stav „World of FRI“
Informatika 2
11
„World of FRI“ – úloha 1
• pridať do hry predmety
• predmety sú v miestnostiach
• predmet môže hráč zdvihnúť a položiť
• príklad: predmet „kamen“
Informatika 2
12
Trieda Predmet – rozhranie
Informatika 2
13
Úpravy závislých tried
• predmety môžu byť
– v miestnosti – trieda Miestnost
– u hráča – trieda Hrac
– vytvorenie a vloženie do miestnosti – trieda MapaHry
Informatika 2
14
Úprava triedy Miestnost
• predmety v miestnosti – atribút aPredmety
• inicializácia atribútu – konštruktor
• uloženie predmetu do miestnosti – metóda
• odobratie predmetu z miestnosti – metóda
Informatika 2
15
Trieda Miestnost – kód(1)
...
private HashMap<String, Predmet> aPredmety;
...
public Miestnost(String paPopis)
{
aPopisMiestnosti = paPopis;
aVychody = new TreeMap<String, Miestnost>();
aPredmety = new HashMap<String, Predmet>();
}
...
Informatika 2
16
Trieda Miestnost – kód(2)
...
public Predmet zoberPredmet(String paNazov)
{
return aPredmety.remove(paNazov);
}
public void polozPredmet(Predmet paPredmet)
{
aPredmety.put(paPredmet.dajNazov(), paPredmet);
}
...
Informatika 2
17
Úprava triedy MapaHry
• položenie predmetu do miestnosti
– konštruktor
Informatika 2
18
Úprava triedy MapaHry – kód
...
aTerasa.nastavVychod("vychod", aAula);
aTerasa.nastavVychod("juh", aLabak);
aTerasa.nastavVychod("sever", aBufet);
aTerasa.polozPredmet(new Predmet("kamen"));
...
Informatika 2
19
Úprava triedy Hrac
• predmety u hráča – atribút aPredmety
• inicializácia atribútu – konštruktor
• zdvihnutie predmetu z akt. miestnosti – metóda
• položenie predmetu do akt. miestnosti - metóda
Informatika 2
20
Trieda Hrac – kód(1)
...
private HashMap<String, Predmet> aPredmety;
...
public Hrac(String paMeno)
{
aMeno = paMeno;
aAktualnaMiestnost = MapaHry.dajInstanciu()
.dajVychodziuMiestnost();
aPredmety = new HashMap<String, Predmet>();
}
...
Informatika 2
21
Trieda Hrac – kód(2)
public void zoberPredmet(String paNazov)
{
Predmet predmet = aAktualnaMiestnost
.zoberPredmet(paNazov);
if (predmet == null) {
System.out.println(
"Nevidim predmet s nazvom " + paNazov);
} else {
aPredmety.put(predmet.dajNazov(), predmet);
}
}
Informatika 2
22
Trieda Hrac – kód(3)
public void polozPredmet(String paNazov)
{
Predmet predmet = aPredmety.remove(paNazov);
if (predmet == null) {
System.out.println(
"Nemas predmet s nazvom " + paNazov);
} else {
aAktualnaMiestnost.polozPredmet(predmet);
}
}
Informatika 2
23
Úpravy príkazov
• nové príkazy pre manipuláciu s predmetmi
– zober predmet
– poloz predmet
– nové triedy VykonavacZozber, VykonavacPoloz
– doplnenie triedy NazvyPrikazov
• rozšírenie príkazu ukaz – trieda Miestnost
– pridať výpis predmetov v miestnosti
Informatika 2
24
Nové príkazy – UML
Informatika 2
25
„World of FRI“ – úloha 2
• pridať popis predmetov
• príkaz ukaz parameter
– hráč môže pozrieť na predmet, ktorý má
• predmet „kamen“:
– „Trochu ziari, ale inak je to uuuplne normalny kamen“
Informatika 2
26
Úpravy triedy Predmet
• nový atribút - aPopis
• nový parameter konštruktora – paPopis
• inicializácia atribúta
• nová metóda dajPopis
Informatika 2
27
Úpravy závislých tried
• trieda MapaHry doplniť vytváranie predmetov a
vkladanie od miestností
• trieda Hrac doplniť prezeranie predmetov
• trieda VykonavacUkaz modifikovať metódu
vykonaj
Informatika 2
28
Trieda VykonavacUkaz – kód
public boolean vykonaj(Hrac paHrac, String paPar)
{
if (paPar == null) {
System.out.println(paHrac
.dajAktualnuMiestnost().dajUplnyPopis());
} else {
System.out.println(paHrac
.dajPopisPredmetu(paPar));
}
return false;
}
Informatika 2
29
„World of FRI“ – úloha 3
• pridať nový predmet naramkoveHodiny
• zobrazuje aktuálny čas
• iné správanie ako kameň
• treba využiť polymorfizmus
• nový interface IPredmet
Informatika 2
30
Triedy pre predmety
Informatika 2
31
Interface IPredmet – kód
public interface IPredmet
{
String dajNazov();
String dajPopis();
}
Informatika 2
32
Úpravy závislých tried
• nahradiť komunikáciu s inštanciami triedy
Predmet – komunikácia cez rozhranie IPredmet
– trieda Miestnost a trieda Hrac – zmena typu Predmet
na typ IPredmet – statický typ
– trieda MapaHry – pridanie predmetu hodiny do mapy
• nová trieda Hodiny
• trieda Predmet – implementuje interface
IPredmet
Informatika 2
33
Úpravy závislých tried
• nahradiť komunikáciu s inštanciami triedy
Predmet – komunikácia cez rozhranie IPredmet
– trieda Miestnost a trieda Hrac – zmena typu Predmet
na typ IPredmet – statický typ
– trieda MapaHry – pridanie predmetu hodiny do mapy
• nová trieda Hodiny
• trieda Predmet – implementuje interface
IPredmet
Informatika 2
34
Trieda Miestnost – kód(1)
...
private HashMap<String, IPredmet> aPredmety;
...
public Miestnost(String paPopis)
{
aPopisMiestnosti = paPopis;
aVychody = new TreeMap<String, Miestnost>();
aPredmety = new HashMap<String, IPredmet>();
}
...
Informatika 2
35
Trieda Miestnost –kód(2)
...
public IPredmet zoberPredmet(String paNazov)
{
return aPredmety.remove(paNazov);
}
...
public void polozPredmet(IPredmet paPredmet)
{
aPredmety.put(paPredmet.dajNazov(), paPredmet);
}
...
Informatika 2
36
Trieda MapaHry – kód
...
aKancelaria.nastavVychod("zapad", aLabak);
aKancelaria.polozPredmet(
new Hodiny("naramkoveHodiny"));
...
Informatika 2
37
Nová trieda Hodiny – kód(1)
import java.util.Date;
import java.text.DateFormat;
public class Hodiny implements IPredmet
{
private String aNazov;
...
}
Informatika 2
38
Nová trieda Hodiny – kód(2)
public Hodiny(String paNazov)
{
aNazov = paNazov;
}
public String dajNazov()
{
return aNazov;
}
...
Informatika 2
39
Nová trieda Hodiny – kód(3)
public String dajPopis()
{
Date cas = new Date();
DateFormat formatCasu =
DateFormat.getTimeInstance();
return "Prave je " + formatCasu.format(cas);
}
Informatika 2
40
Priebeh hry – príkazy zober, ukaz
Informatika 2
41
Testovanie
• testovanie tried pre priamu komunikáciu s
hráčom (používateľom)
• výsledok činnosti metódy je vypísaný do
terminálového okna
• System.out.print(...)
• System.out.println(...)
Informatika 2
42
Priama komunikácia
Informatika 2
43
Terminal – prostredník
Informatika 2
44
Interface ITerminal
Informatika 2
45
Testovacia trieda
Informatika 2
46
Interface ITerminal – kód
public interface ITerminal
{
void vypis(String paRiadok);
}
Informatika 2
47
Trieda SkutocnyTerminal
public class SkutocnyTerminal implements ITerminal
{
public void vypis(String paRiadok)
{
System.out.println(paRiadok);
}
}
Informatika 2
48
Trieda TestovaciTerminal(1)
public class TestovaciTerminal implements ITerminal
{
private String aVystup;
public TestovaciTerminal()
{
aVystup = "";
}
...
}
Informatika 2
49
Trieda TestovaciTerminal(2)
...
public void vypis(String paRiadok)
{
aVystup += paRiadok + "\n";
}
public String dajVypis()
{
return aVystup;
}
Informatika 2
50
Testovaná a testovacia trieda
Informatika 2
51
Trieda VykonavacPomoc(1)
public class VykonavacPomoc
implements IVykonavac
{
private ITerminal aTerminal;
public VykonavacPomoc(ITerminal paTerminal)
{
aTerminal = paTerminal;
}
...
}
Informatika 2
52
Trieda VykonavacPomoc(2)
public boolean vykonaj(
Hrac paHrac, String paParameter)
{
aTerminal.vypis("Zabludil si. Si sam. Tulas sa po fakulte.");
aTerminal.vypis("");
aTerminal.vypis("Mozes pouzit tieto prikazy:");
aTerminal.vypis(" chod ukonci pomoc");
return false;
}
Informatika 2
53
VykonavaceTest – Prípravky
private TestovaciTerminal terminal;
private Hrac hrac;
private VykonavacPomoc vykonavac;
@Before
protected void setUp()
{
terminal = new TestovaciTerminal();
hrac = new Hrac("Test")
vykonavac = new VykonavacPomoc(terminal);
}
Informatika 2
54
VykonavaceTest – Testovacia metóda
public void testVykonavacPomoc()
{
String ocakavany =
"Zabludil si. Si sam. Tulas sa po fakulte.\n" +
"Mozes pouzit tieto prikazy:\n" +
" chod ukonci pomoc\n";
assertFalse(vykonavac.vykonaj(hrac, null));
assertEquals(ocakavany, terminal.dajVypis());
}
Informatika 2
55
Výsledok testov
Informatika 2
56
57
Informatika 2
Testovanie – vykonávače(1)
58
Informatika 2
Testovanie – vykonávače(2)
Testovanie – Parser
• čítanie z klávesnice a testovanie
• rozšírenie terminálu o čítanie klávesnice
• skutočný terminál preberá vstup od System.in
• testovací terminál dostáva vstup ako parameter
konštruktora
• detaily realizácie – projekt na vzdelávaní
Informatika 2
59
60
Informatika 2
Testovanie – vykonávače(3)
61
Informatika 2
Testovanie – vykonávače(4)
Dependency injection
• slovensky: vkladanie závislostí
• návrhový vzor
• znižovanie implementačnej závislosti pomocou
polymorfizmu
– nahradenie závislosti pomocou interface
• zlepšenie možnosti testovania aplikácie
Informatika 2
62
„World of FRI“ – úloha 4
• pridať predmet walkman
– prehráva hudbu
– dá sa zapnúť
– nefunguje bez bateriek
• pridať predmet baterky
– dajú sa vložiť do walkmanu
Informatika 2
63
Vyžadované zmeny
• každý predmet sa musí dať použiť
– nový príkaz pouzi
– nová trieda VykonavacPouzi
– nová položka do zoznamu v triede NazvyPrikazov
• nová správa pouzi do interface IPredmet
– hráč musí vedieť použiť držaný predmet
– nová metóda pouziPredmet(String paNazov) do triedy
Hrac
Informatika 2
64
Nová správa – pouzi
• parameter paHrac – hráč, ktorý predmet používa
• návratová hodnota – odpoveď hráčovi vo forme
reťazca, zobrazí sa v termináli
Informatika 2
65
String pouzi(Hrac paHrac)
Nová správa – pouzi
Informatika 2
66
Nové predmety
Informatika 2
67
Nový predmet – walkman
• dajNazov – vráti názov (walkman)
• dajPopis – informuje o možnosti objekt spustiť
• pouzi – po vložení batérií pustí hudbu – vypíše
text na terminál
Informatika 2
68
Nový predmet – baterky
• dajNazov – vráti názov (baterky)
• dajPopis – nejaký vtipný popis bateriek
• pouzi – zistí, či hráč drží walkman, ak áno, vloží
doň baterky
Informatika 2
69
Trieda Walkman(1)
public class Walkman implements IPredmet
{
private String aNazov;
private boolean aMaBaterky;
public Walkman(String paNazov)
{
aNazov = paNazov;
aMaBaterky = false;
}
...
}
Informatika 2
70
Trieda Walkman(2)
public String dajPopis()
{
return "Walkman. Ma cudlik na zapnutie.";
}
public String dajNazov()
{
return aNazov;
}
Informatika 2
71
Trieda Walkman(3)
public String pouzi(Hrac paHrac)
{
if (aMaBaterky) {
return "La.. laaa~ walkmen vyhravaaaa~";
} else {
return "Nema baterky";
}
}
Informatika 2
72
Trieda Walkman(4)
public void vlozBaterky()
{
aMaBaterky = true;
}
Informatika 2
73
Trieda Baterky(1)
public class Baterky implements IPredmet
{
private String aNazov;
public Baterky(String paNazov)
{
aNazov = paNazov;
}
...
}
Informatika 2
74
Trieda Baterky(2)
public String dajNazov()
{
return aNazov;
}
public String dajPopis()
{
return "Tie baterky so zajacom, co hra fotbal.
Nebudem robit reklamu...";
}
Informatika 2
75
Trieda Baterky(3)
public String pouzi(Hrac paHrac)
{
Walkman walkman =
paHrac.dajPredmet("walkman");
if (walkman == null)
return "Nemas ich ako pouzit";
paHrac.vyberPredmet(aNazov);
walkman.vlozBaterky();
return "Vlozil si baterky do walkmana.";
}
Informatika 2
76
Chyba pri preklade
Informatika 2
77
Trieda Baterky – správne
public String pouzi(Hrac paHrac)
{
IPredmet pred = paHrac.dajPredmet("walkman");
Walkman walkman = (Walkman) pred;
if (walkman == null)
return "Nemas ich ako pouzit";
paHrac.vyberPredmet(aNazov);
walkman.vlozBaterky();
return "Vlozil si baterky do walkmana.";
}
Informatika 2
78
Pretypovanie
• zmena statického typu
• zmena množiny správ, ktoré je možné poslať
• implicitné
• explicitné
Informatika 2
79
Implicitné pretypovanie
• automatické pretypovanie
• iba obmedzenie množiny správ
• vykonáva a kontroluje prekladač pri preklade
• statický typ musí byť typovo kompatibilný s
cieľovým typom
• literál null sa dá implicitne pretypovať na
ľubovoľný objektový typ
Informatika 2
80
IPredmet predmet = new Walkman();
Explicitné pretypovanie
• pretypovanie „na požiadanie“
• rozšírenie, alebo výmena množiny správ
• prekladač robí iba čiastočnú kontrolu
• vykonáva a kontroluje JVM za behu programu
• dynamický typ musí byť typovo kompatibilný s
cieľovým typom
• hodnota null sa dá explicitne pretypovať na
ľubovoľný objektový typ
Informatika 2
81
Explicitné pretypovanie – príklad
• nový typ do zátvorky pred výraz, ktorý má byť
pretypovaný
Informatika 2
82
Walkman predmet =
(Walkman)paHrac.dajPredmet("walkman");
83
Informatika 2
Pretypovanie(1)
Implicitné
I
Explicitné
E
Pretypovanie(2)
IPredmet predmet;
Walkmen walkmen = new Walkmen();
predmet = walkmen; // OK
walkmen = predmet; // Chyba
walkmen = (Walkmen) predmet; // OK
Informatika 2
84
Vďaka za pozornosť
Automaticky vygenerovaný textový náhľad. Pre plné formátovanie si stiahnite súbor.
nechodím na prednášky