Mikuláš je tu! Získaj 90 % extra kreditov ZADARMO s promo kódom CERTIK90 pri nákupe od 1 199 kreditov. Len do nedele 7. 12. 2025! Zisti viac:
NOVINKA: Najžiadanejšie rekvalifikačné kurzy teraz s 50% zľavou + kurz AI ZADARMO. Nečakaj, táto ponuka dlho nevydrží! Zisti viac:

4. diel - Hracia kocka v Jave - Zapuzdrenie a konštruktor

V predchádzajúcom cvičení, Riešené úlohy k 3. 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.

Základné piliere OOP

OOP stojí na troch základných pilieroch:

  • Zapuzdrenie
  • Dedičnosť
  • Polymorfizmus

Dnes použijeme prvý z nich.

Vytvorenie projektu

Vytvorme si nový projekt a pomenujme ho ArenaFight. K projektu si pridajme novú triedu s názvom RollingDie. Zamyslime sa nad atribútmi, ktoré kocke dáme. Určite by sa hodilo, keby sme si mohli zvoliť počet strán kocky (klasicky 6 alebo 10 strán, ako býva zvykom pri tomto type hier). Naša trieda preto bude mať atribút sidesCount. Triedu RollingDie upravíme do nasledujúcej podoby:

/**
 * Class representing a die for a board game
 */
public class RollingDie {
    /**
     * Number of sides that the die has
     */
    public int sidesCount;
}

Konštruktory

Konštruktor je špeciálna metóda, ktorá sa sama zavolá vo chvíli vytvorenia inštancie objektu. Slúži na nastavenie vnútorného stavu objektu a na vykonanie prípadnej inicializácie. Prejdeme do súboru Main.java, kde kocku vytvoríme týmto spôsobom:

RollingDie die = new RollingDie();

Práve RollingDie() je konštruktor. Pretože v našej triede žiadny nie je, Java si sama vygeneruje prázdny konštruktor. 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 názov triedy (začína teda, na rozdiel od ostatných metód, veľkým písmenom), v našom prípade teda RollingDie. V konštruktore nastavíme počet strán na pevnú hodnotu.

Prejdeme do súboru RollingDie.java a pridáme do triedy metódu RollingDie(). V nej nastavíme hodnotu atribútu sidesCount:

/**
 * Class representing a die for a board game
 */
public class RollingDie{
     /**
      * Number of sides that the die has
      */
     public int sidesCount;

     /**
      * Creates an instance of a new rolling die
      */
     public RollingDie() {
         sidesCount = 6;
     }
}

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

        RollingDie die = new RollingDie(); // at this point the constructor is called
        System.out.println(die.sidesCount);

V konzole vidíme výstup:

Attribute sidesCount:
6

Vidíme, že sa konštruktor naozaj zavolal.

Voliteľný počet strán

My by sme však chceli, aby sme mohli pri každej kocke pri vytvorení špecifikovať, koľko strán budeme potrebovať. Prejdeme do súboru RollingDie.java a dáme teda konštruktoru parameter:

public RollingDie(int newSidesCount) {
       sidesCount = newSidesCount;
}

Všimnite si, že sme pred názov parametra metódy pridali slovo new, pretože inak by mal rovnaký názov ako atribút a Javu by to zmätlo. Vráťme sa do súboru Main.java a zadajme tento parameter do konštruktora:

        RollingDie die = new RollingDie(10); // at this moment the constructor with parameter 10 will be called
        System.out.println(die.sidesCount);

V konzole vidíme výstup:

Output with constructor parameter 10:
10

Všetko funguje, ako sme očakávali.

Východisková hodnota kocky

Java nám už v tomto momente nevygeneruje prázdny (tzv. bezparametrický) konštruktor, takže kocku bez parametra už 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 strán na 6, pretože takúto hodnotu asi používateľ našej triedy u kocky očakáva ako východiskovú. Prejdeme teda späť do súboru RollingDie.java a vytvoríme konštruktor bez parametra:

public RollingDie() {
    sidesCount = 6;
}

Trieda RollingDie má teda teraz dva konštruktory.

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

        RollingDie sixSided = new RollingDie();
        RollingDie tenSided = new RollingDie(10);
        System.out.println(sixSided.sidesCount);
        System.out.println(tenSided.sidesCount);

Výstup:

Konzolová aplikácia
6
10

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 RollingDie() (teda tu konštruktor) má pretiaženie (overload). To môžeme využívať aj u všetkých ďalších metód, nielen u konštruktorov. IDE nám prehľadne ponúka všetky pretiaž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

Mnoho metód v Jave má hneď niekoľko pretížení, skúste sa pozrieť napr. na metódu indexOf() na triede String. Je dobré si u metód prejsť ich pretiaženia, aby ste neprogramovali niečo, čo už niekto urobil pred vami.

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

public RollingDie(int sidesCount) {
    sidesCount = sidesCount;
}

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í. Vo vnútri triedy máme možnosť odkazovať sa na jej inštanciu, je uložená v premennej this. Využitie si môžeme predstaviť napr. keby kocka mala metódu giveToPlayer(Player player) a tam by volala player.pickUpDie(this). Tu by sme hráčovi pomocou referenčnej premennej this odovzdali samých seba, 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:

public RollingDie(int sidesCount) {
    this.sidesCount = sidesCount;
}

Pomocou premennej this sme špecifikovali, že ľavá premenná sidesCount 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.

Zapuzdrenie

Zapuzdrenie umožňuje skryť niektoré metódy a atribúty tak, aby zostali použiteľné len pre triedu zvnútra. Objekt si môžeme predstaviť ako čiernu skrinku (anglicky blackbox), ktorá má určité rozhranie (interface), cez ktoré jej odovzdávame inštrukcie/dáta a ona ich spracováva.

Nevieme, ako to vnútri funguje, ale vieme, ako sa navonok správa a používa. Nemôžeme teda spôsobiť nejakú chybu, pretože využívame a vidíme len to, čo tvorca triedy sprístupnil.

Príkladom môže byť trieda Human, ktorá bude mať atribút birthDate a na jeho základe ďalšie atribúty ako adult a age. Keby niekto objektu zvonku zmenil birthDate, prestali by platiť premenné adult a age. Hovoríme, že vnútorný stav objektu by bol nekonzistentný. Toto sa nám v štruktúrovanom programovaní môže pokojne stať. V OOP však objekt zapuzdríme. Atribút birthDate označíme ako privátny a tým pádom bude jasné, že nechceme, aby nám ho niekto len tak menil. Naopak navonok vystavíme metódu changeBirthDate(), ktorá dosadí nové dátum narodenia do premennej birthDate a zároveň vykoná potrebný prepočet veku a prehodnotenie plnoletosti. Použitie objektu je bezpečné a aplikácia stabilná.

Zapuzdrenie teda núti programátorov používať objekt len tým správnym spôsobom. Rozhranie (interface) triedy rozdelí na verejne prístupné (public) a vnútornú štruktúru (private).

Zapuzdrenie atribútu sidesCount

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 vnútri triedy a zvonku sa Java tvári, že vôbec neexistuje. Pri návrhu triedy teda nastavíme všetko na private a v prípade, že niečo bude naozaj potrebné vystaviť, použijeme modifikátor public. Naša trieda teraz vyzerá takto:

/**
 * Class representing a die for a board game
 */
public class RollingDie{
     /**
      * Number of sides that the die has
      */
     private int sidesCount;

Teraz nám nebude môcť nikto u už vytvorenej kocky meniť počet strán. Umožníme však počet strán zvonku prečítať. V súbore RollingDie.java pridáme do triedy metódu getSidesCount(), ktorá nám vráti hodnotu atribútu sidesCount. Docielili sme tým v podstate to, že je atribút read-only (atribút nie je viditeľný a možno ho len čítať metódou, zmeniť ho nemožno). Nová metóda bude vyzerať asi takto:

/**
 * Returns the number of sides the die has
 *
 * @return Number of sides the die has
 */
public int getSidesCount() {
   return sidesCount;
}

Presuňme sa do súboru Main.java a upravme výpis počtu strán na použitie novej metódy:

        RollingDie sixSided = new RollingDie();
        RollingDie tenSided = new RollingDie(10);
        System.out.println(sixSided.getSidesCount());
        System.out.println(tenSided.getSidesCount());

Po spustení programu v konzole vidíme výstup:

Output of getSidesCount() method:
6
10

V nasledujúcej lekcii, Hracia kocka v Jave druhýkrát - Prekrývanie metód a random, sa naučíme prekrývať metódy, pracovať s náhodnými číslami a dokončíme hraciu kocku.


 

Mal si s čímkoľvek problém? Zdrojový kód vzorovej aplikácie je k stiahnutiu každých pár lekcií. Zatiaľ pokračuj ďalej, a potom si svoju aplikáciu porovnaj so vzorom a ľahko opráv.

Predchádzajúci článok
Riešené úlohy k 3. lekcii OOP v Jave
Všetky články v sekcii
Objektovo orientované programovanie v Jave
Preskočiť článok
(neodporúčame)
Hracia kocka v Jave druhýkrát - Prekrývanie metód a random
Článok pre vás napísal David Hartinger
Avatar
Užívateľské hodnotenie:
143 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