IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

3. diel - Hracia kocka v Jave - Zapuzdrenie, konštruktor a Random

V predchádzajúcom cvičení, Riešené úlohy k 2. lekcii OOP v Jave, sme si precvičili získané skúsenosti z predchádzajúcich lekcií.

V dnešnom tutoriáli začneme pracovať na sľúbenej aréne, v ktorej budú proti sebe bojovať dvaja bojovníci. Boj bude ťahový (na preskáčku) a bojovník vždy druhému uberie život na základe sily jeho útoku a obrany druhého bojovníka. Simulujeme v podstate stolnú hru, budeme teda simulovať aj hraciu kocku, ktorá dodá hre prvok náhodnosti. Začnime zvoľna a vytvorme si dnes práve túto hraciu kocku. Zároveň sa naučíme ako definovať vlastný konštruktor.

Vytvorenie projektu

Vytvorme si nový projekt a pomenujme ho TahovyBoj. K projektu si pridajme novú triedu s názvom Kostka. Zamyslime sa nad atribútmi, ktoré kocke dáme. Iste by sa hodilo, keby sme si mohli zvoliť počet stien kocky (klasicky 6 alebo 10 stien, ako je zvykom pri tomto type hier). Ďalej bude kocka potrebovať tzv. generátor náhodných čísel. Ten nám samozrejme poskytne Java, ktorá na tieto účely obsahuje triedu Random. Aby sme ju mohli používať, musíme si triedu java.util.Random naimportovať. Import napíšeme hore, ako sme zvyknutí z používania importu pre Scanner. Naša trieda bude mať teraz 2 atribúty:

  • pocetSten typu int a
  • random typu Random, kde bude náhodný generátor.
Zapuzdrenie

Minule sme kvôli jednoduchosti nastavovali všetky atribúty našej triedy ako public, teda ako verejne prístupné. Väčšinou sa však skôr nechce, aby sa dali zvonku modifikovať a používa sa modifikátor private. Atribút je potom viditeľný len vo vnútri triedy a zvonku sa Java tvári, že vôbec neexistuje. Pri návrhu triedy teda nastavíme všetko na private av prípade, že niečo bude naozaj potrebné vystaviť, použijeme modifikátor public. Naša trieda teraz vyzerá takto:

Riadok:

nám hovorí: nastav ako privátny (neverejný) atribút random dátového typu Random. Uložíme tak do atribútu celú triedu Random a môžeme v triede v akejkoľvek metóde volať napríklad metódu random.nextInt(), bez toho aby sme tam znovu zakladali premennú.

Konštruktory

Až doteraz sme nevedeli zvonku nastaviť iné atribúty ako public, pretože napr. private nie sú zvonku viditeľné. Už sme si hovorili niečo málo o konštruktore objektu. Je to metóda, ktorá sa zavolá vo chvíli vytvorenia inštancie objektu. Slúži samozrejme na nastavenie vnútorného stavu objektu a na vykonanie prípadnej inicializácie. Inštanciu kocky by sme teraz v súbore TahovyBoj.java vytvorili takto:

Práve slovo Kostka() je konštruktor. Pretože v našej triede Kostka žiadny konštruktor nie je, Java si dogeneruje prázdnu metódu. My si však teraz konštruktor do triedy pridáme. Deklaruje sa ako metóda, ale nemá návratový typ a musí mať rovnaký názov ako je názov triedy (začína teda, na rozdiel od ostatných metód, veľkým písmenom), v našom prípade teda Kostka. V konštruktore nastavíme počet stien na pevnú hodnotu a vytvoríme inštanciu triedy Random. Konštruktor bude vyzerať nasledovne:

Ak kocku teraz vytvoríme, bude mať atribút pocetSten hodnotu 6 av atribúte random bude vytvorená inštancia generátora náhodných čísel. Vypíšme si počet stien do konzoly, nech vidíme, že tam hodnota naozaj je. Nie je dobré atribút nastaviť na public, pretože nebudeme chcieť, aby nám niekto mohol už pri vytvorenej kocke meniť počet stien. Pridáme do triedy teda metódu vratPocetSten(), ktorá nám vráti hodnotu atribútu pocetSten. Docielili sme tým v podstate to, že je atribút read-only (atribút nie je viditeľný a možno ho iba čítať metódou, zmeniť ho nemožno). Nová metóda bude vyzerať asi takto:

Presuňme sa do súboru TahovyBoj.java a vyskúšajme si vytvoriť kocku a vypísať počet stien:

Výstup:

Vidíme, že sa konštruktor naozaj zavolal. My by sme ale chceli, aby sme mohli pri každej kocke pri vytvorení špecifikovať, koľko stien budeme potrebovať. Prejdeme do triedy Kostka.java a dáme teda konštruktoru parameter:

Všimnite si, že sme pred názov parametra metódy pridali znak a, pretože inak by mal rovnaký názov ako atribút a Javu by to zmiatlo. Vráťme sa do súboru TahovyBoj.java a zadajte tento parameter do konstruktoru:

Výstup:

Všetko funguje, ako sme očakávali. Java nám už v tejto chvíli nevygeneruje prázdny (tzv. bezparametrický konštruktor), takže kocku bez parametra vytvoriť nemožno. My to však môžeme umožniť, vytvorme si ďalší konštruktor a tentoraz bez parametra. V ňom nastavíme počet stien na 6, pretože takú hodnotu asi užívateľ našej triedy pri kocke očakáva ako východiskový. Prejdeme teda späť do súboru Kostka.java a vytvoríme konštruktor bez parametra:

Trieda Kostka má teda teraz dvoch konštruktorov.

Skúsme si teraz vytvoriť 2 inštancie kocky, každú iným konštruktorom v súbore TahovyBoj.java:

Výstup:

Jave nevadí, že máme dve metódy s rovnakým názvom, pretože ich parametre sú rôzne. Hovoríme o tom, že metóda Kostka() (teda tu konštruktor) má preťaženie (overload). To môžeme využívať aj pri všetkých ďalších metódach, nielen pri konštruktoroch. IDE nám prehľadne ponúka všetky preťaženia metódy vo chvíli, keď zadáme jej názov. V ponuke vidíme naše 2 konštruktory:

  • .<> Nápoveda k preťaženým metódam v Jave  - Objektovo orientované programovanie v Jave - Objektovo orientované programovanie v Jave
  • .<> Nápoveda k preťaženým metódam v Jave  - Objektovo orientované programovanie v Jave - Objektovo orientované programovanie v Jave
Veľa metód v Jave má hneď niekoľko preťažení, skúste sa pozrieť napr. na metódu indexOf() na triede String. Je dobré si pri metódach prejsť ich preťaženie, aby ste neprogramovali niečo, čo už niekto urobil pred vami.

Ukážeme si ešte, ako ide obísť nepraktický názov atribútu u parametrického konštruktora (v našom prípade aPocetSten) a potom konštruktory opustíme. Problém je samozrejme v tom, že keď napíšeme:

Java nevie, ktorú z premenných myslíme, či parameter alebo atribút. V tomto prípade priraďujeme do parametra znovu ten istý parameter. IDE nás na túto skutočnosť dokonca upozorní. Vnútri triedy sa máme možnosť odkazovať na jej inštanciu, je uložená v premennej this. Využitie si môžeme predstaviť napr. keby kocka mala metódu dejHraci(Hrac hrac) a tam by volala hrac.seberKostku(this). Tu by sme hráči pomocou referenčnej premennej this odovzdali seba samého, teda tú konkrétnu kocku, s ktorou pracujeme. My sa tým tu nebudeme zaťažovať, ale využijeme odkaz na inštanciu pri nastavovaní atribútu:

Pomocou premennej this sme špecifikovali, že ľavá premenná pocetSten patrí inštancii, pravú Java chápe ako z parametra. Máme teda dva konštruktory, ktoré nám umožňujú tvoriť rôzne hracie kocky. Prejdime ďalej.

Náhodné čísla

Definujme na kocke metódu hod(), ktorá nám vráti náhodné číslo od 1 do počtu stien. Je to veľmi jednoduché, metóda bude public (pôjde volať zvonku triedy) a nebude mať žiadny parameter. Návratová hodnota bude typu int. Náhodné číslo získame tak, že na generátore random zavoláme metódu nextInt(). Tá má dve preťaženia:

  • nextInt() - Variant bez parametra vracia náhodné číslo v celom rozsahu dátového typu int, pre úplnosť teda konkrétne od -2147483648 do 2147483647.
  • nextInt(do) - Vracajú nezáporné čísla menšie ako medza do. Napríklad random.nextInt(100) teda vráti číslo od 0 do 99.
Na naše účely sa najlepšie hodí druhé preťaženie, píšeme do súboru Kostka.java teda:

Dajte si pozor, aby ste netvorili generátor náhodných čísel v metóde, ktorá má náhodné číslo vracať, teda že by sa pre každé náhodné číslo vytvoril nový generátor. Výsledné čísla potom nie sú takmer náhodné alebo dokonca vôbec. Vždy si vytvorte jednu zdieľanú inštanciu generátora (napr. do privátneho atribútu pomocou konštruktora) a na tej potom metódu nextInt() volajte.

Prekrývanie metódy toString()

Kocka je takmer hotová, ukážme si ešte jednu užitočnú metódu, ktorú ju pridáme a ktorú budeme hojne používať aj vo väčšine našich ďalších objektov. Reč je o metóde toString(), o ktorej sme sa už zmienili a ktorú obsahuje každý objekt, teda aj teraz naša kocka. Metóda je určená na to, aby vrátila tzv. textovú reprezentáciu inštancie. Hodí sa vo všetkých prípadoch, keď si inštanciu potrebujeme vypísať alebo s ňou pracovať ako s textom. Túto metódu majú napr. aj čísla. Už vieme, že v Jave funguje implicitná konverzia, akonáhle teda budeme chcieť do konzoly vypísať objekt, Java na ňom zavolá metódu toString() a vypíše jej výstup. Ak si robíme vlastnú triedu, mali by sme zvážiť, či sa nám takáto metóda nehodí. Nikdy by sme si nemali robiť vlastnú metódu, napr. niečo ako vypis() (čo sme používali doteraz), keď máme v Jave pripravenú cestu, ako toto riešiť. U kocky nemá metóda toString() vyšší zmysel, ale u bojovníka bude určite vracať jeho meno. My si ju ku kocke aj tak pridáme, bude vypisovať, že sa jedná o kocku a vráti aj počet stien. Najprv si skúsme vypísať do konzoly našu inštanciu kocky:

Do konzoly sa vypíše iba cesta k našej triede, teda cz.itnetwork.Kostka a tzv. hash kód objektu. V mojom prípade bol vypísaný tento reťazec:

Metódu toString() už jednoducho nedefinujeme, ale pretože už existuje, musíme ju prepísať, resp. prekryť. Tým sa opäť nebudeme teraz podrobne zaoberať, ale chcem, aby sme už teraz vedeli metódu toString() používať. Pre prehľadné prekrytie označíme metódu anotácií @Override:

Teraz opäť skúsime do konzoly vypísať priamo inštanciu kocky.

Výstup:

Ešte si naše kocky vyskúšame. Skúsime si v programe s našimi dvoma kockami v cykloch hádzať a pozrieme sa, či fungujú tak, ako sa očakáva:

Výstup môže vyzerať nejako takto:

Máme hotovú celkom peknú a nastaviteľnú triedu, ktorá reprezentuje hraciu kocku. Bude sa nám hodiť v našej aréne, ale môžete ju použiť aj kdekoľvek inde. Vidíme, ako OOP umožňuje znovupoužívať komponenty.

V nasledujúcom cvičení, Riešené úlohy k 3. lekcii OOP v Jave, si precvičíme nadobudnuté skúsenosti z predchádzajúcich lekcií.


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 2255x (9.37 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Java

 

Predchádzajúci článok
Riešené úlohy k 2. lekcii OOP v Jave
Všetky články v sekcii
Objektovo orientované programovanie v Jave
Preskočiť článok
(neodporúčame)
Riešené úlohy k 3. lekcii OOP v Jave
Článok pre vás napísal David Hartinger
Avatar
Užívateľské hodnotenie:
1 hlasov
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David sa informačné technológie naučil na Unicorn University - prestížnej súkromnej vysokej škole IT a ekonómie.
Aktivity