Lekce 5 - Hrací kostka v Javě podruhé - Překrývání metod a random
V minulé lekci, Hrací kostka v Javě - Zapouzdření a konstruktor, jsme začali vytvářet první pořádný objekt, byla jím hrací kostka.
V tomto tutoriálu objektově orientovaného programování v Javě budeme pokračovat v tvorbě naší objektové hrací kostky. Začneme s metodou pro hod. Vysvětlíme si na ní práci s náhodnými čísly a poté prozkoumáme principy překrývání metod.
Náhodná čísla
V Javě máme pro generování náhodných čísel k dispozici třídu
Random
. Abychom ji mohli používat, musíme si třídu
java.util.Random
v souboru Kostka.java
nejprve
naimportovat. Import napíšeme nahoru, jak jsme zvyklí z používání importu
pro Scanner
. Následně přidáme třídě Kostka
privátní atribut random
typu Random
, kde bude
náhodný generátor čísel:
import java.util.Random; /** * Třída reprezentuje hrací kostku */ public class Kostka { /** * Generátor náhodných čísel */ private Random random; /** * Počet stěn kostky */ private int pocetSten;
Dále v konstruktorech vytvoříme instanci třídy Random
.
Upravené konstruktory budou vypadat následovně:
/** * Vytvoří novou instanci hrací kostky */ public Kostka() { pocetSten = 6; random = new Random(); } /** * Vytvoří novou instanci hrací kostky * @param pocetSten Počet stěn hrací kostky */ public Kostka(int pocetSten) { this.pocetSten = pocetSten; random = new Random(); }
Hod kostkou
Nyní můžeme ve třídě Kostka
definovat další metodu.
Nazveme ji hod()
:
/** * Vykoná hod kostkou * @return Číslo od 1 do počtu stěn */ public int hod() { return random.nextInt(pocetSten) + 1; }
Metoda nám vrátí náhodné číslo od jedné do počtu stěn, bude
public
(půjde volat zvenčí třídy) a nebude mít žádný
parametr. Návratová hodnota bude typu int
. Náhodné číslo
získáme tak, že na generátoru random
zavoláme metodu
nextInt()
. Ta má dvě přetížení:
nextInt()
- Varianta bez parametru vrací náhodné číslo v celém rozsahu datového typuint
, pro úplnost tedy konkrétně od-2147483648
do2147483647
.nextInt(do)
- Vrací nezáporná čísla menší než mezdo
. Napříkladrandom.nextInt(100)
tedy vrátí číslo od0
do99
.
Pro naše účely se nejlépe hodí druhé přetížení. Dejte si pozor,
abyste netvořili generátor náhodných čísel v metodě, která má náhodné
číslo vracet, tedy že by se pro každé náhodné číslo vytvořil nový
generátor. Výsledná čísla pak nejsou téměř náhodná nebo dokonce
vůbec. Vždy si vytvořte jednu sdílenou instanci generátoru (např. do
privátního atributu pomocí konstruktoru) a na té potom metodu
nextInt()
volejte.
Překrývání metody
toString()
Kostka je téměř hotová. Ukažme si teď ještě jednu užitečnou metodu,
kterou budeme hojně používat i ve většině našich dalších objektů.
Řeč je o metodě toString()
. Tuto metodu obsahuje
každý objekt, tedy i nyní naše kostka. Metoda je určena k
tomu, aby vrátila tzv. textovou reprezentaci instance. Hodí
se ve všech případech, kdy si instanci potřebujeme vypsat nebo s ní
pracovat jako s textem. Tuto metodu mají např. i čísla. Již víme, že v
Javě funguje implicitní konverze. Jakmile tedy budeme chtít
do konzole vypsat objekt, Java na něm zavolá metodu toString()
a
vypíše její výstup. Pokud si děláme vlastní třídu, měli bychom
zvážit, zda se nám takováto metoda nehodí. Nikdy bychom si neměli
dělat vlastní metodu, např. něco jako vypis()
(co jsme
používali dosud), když máme v Javě připravenou cestu, jak toto řešit. U
kostky nemá metoda toString()
vyšší smysl, ale u bojovníka
bude jistě vracet jeho jméno. My si ji ke kostce stejně přidáme, bude
vracet, že se jedná o kostku a vrátí i počet stěn. Nejprve si zkusme
vypsat do konzole naši instanci kostky:
{JAVA_OOP} {JAVA_MAIN_BLOCK} Kostka sestistenna = new Kostka(); Kostka desetistenna = new Kostka(10); System.out.println(sestistenna); {/JAVA_MAIN_BLOCK} {/JAVA_OOP}
{JAVA_OOP} import java.util.Random; public class Kostka { private Random random; private int pocetSten; public Kostka() { pocetSten = 6; random = new Random(); } public Kostka(int pocetSten) { this.pocetSten = pocetSten; random = new Random(); } public int vratPocetSten() { return pocetSten; } public int hod() { return random.nextInt(pocetSten) + 1; } } {/JAVA_OOP}
Do konzole se vypíše pouze cesta k naší třídě, tedy
cz.itnetwork.Kostka
a tzv. hash kód objektu. V mém případě byl
vypsán tento řetězec:
Konzolová aplikace
cz.itnetwork.Kostka@7c1c8c58
Metodu toString()
již jednoduše nedefinujeme, ale protože
již existuje, musíme ji přepsat, resp. překrýt. Tím se
opět nebudeme nyní podrobně zabývat, nicméně chceme, abychom již teď
uměli metodu toString()
používat. Pro přehledné překrytí
označíme metodu anotací @Override
:
{JAVA_OOP} import java.util.Random; public class Kostka { private Random random; private int pocetSten; public Kostka() { pocetSten = 6; random = new Random(); } public Kostka(int pocetSten) { this.pocetSten = pocetSten; random = new Random(); } public int vratPocetSten() { return pocetSten; } public int hod() { return random.nextInt(pocetSten) + 1; } /** * Vrací textovou reprezentaci kostky * @return Textová reprezentace kostky */ @Override public String toString() { return String.format("Kostka s %s stěnami", pocetSten); } } {/JAVA_OOP}
{JAVA_OOP} {JAVA_MAIN_BLOCK} Kostka sestistenna = new Kostka(); Kostka desetistenna = new Kostka(10); System.out.println(sestistenna); {/JAVA_MAIN_BLOCK} {/JAVA_OOP}
Nyní opět zkusíme do konzole vypsat přímo instanci kostky.
Výstup:
Konzolová aplikace
Kostka s 6 stěnami
Ještě si naše kostky vyzkoušíme. Zkusíme si v programu s našima dvěma kostkami v cyklech házet a podíváme se, jestli fungují tak, jak se očekává:
{JAVA_OOP} {JAVA_MAIN_BLOCK} // vytvoření kostek Kostka sestistenna = new Kostka(); Kostka desetistenna = new Kostka(10); // hod šestistěnnou kostkou System.out.println(sestistenna); for (int i = 0; i < 10; i++) { System.out.print(sestistenna.hod() + " "); } // hod desetistěnnou kostkou System.out.println("\n\n" + desetistenna); for (int i = 0; i < 10; i++) { System.out.print(desetistenna.hod() + " "); } {/JAVA_MAIN_BLOCK} {/JAVA_OOP}
{JAVA_OOP} import java.util.Random; public class Kostka { private Random random; private int pocetSten; public Kostka() { pocetSten = 6; random = new Random(); } public Kostka(int pocetSten) { this.pocetSten = pocetSten; random = new Random(); } public int vratPocetSten() { return pocetSten; } public int hod() { return random.nextInt(pocetSten) + 1; } @Override public String toString() { return String.format("Kostka s %s stěnami", pocetSten); } } {/JAVA_OOP}
Výstup může vypadat nějak takto:
Konzolová aplikace
Kostka s 6 stěnami
3 6 6 1 6 3 6 2 6 3
Kostka s 10 stěnami
5 9 9 2 10 4 9 3 10 5
Máme hotovou docela pěknou a nastavitelnou třídu, která reprezentuje hrací kostku. Bude se nám hodit v naší aréně, ale můžete ji použít i kdekoli jinde. Vidíme, jak OOP umožňuje znovupoužívat komponenty.
V následujícím cvičení, Řešené úlohy k 4.-5. lekci OOP v Javě, si procvičíme nabyté zkušenosti z předchozích lekcí.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 3x (9.85 kB)
Aplikace je včetně zdrojových kódů v jazyce Java