5. diel - Hracia kocka v C# druhýkrát - Prekrývanie metód a random
V minulej lekcii, Hracia kocka v C# - Zapuzdrenie a konštruktor, sme vytvorili svoj prvý poriadny objekt, bola ním hracia kocka.
V tomto tutoriáli objektovo orientovaného programovania v C# budeme pokračovať v tvorbe našej objektovej hracej kocky. Začneme s metódou pre hod. Vysvetlíme si na nej prácu s náhodnými číslami a následne preskúmame princípy prekrývania metód.
Náhodné čísla
V .NET frameworku máme na generovanie náhodných čísel k dispozícii
triedu Random. Prejdeme do súboru RollingDie.cs a
pridáme triede RollingDie privátny atribút random
typu Random, kde bude náhodný generátor čísel:
/// <summary> /// Class representing a die for a board game /// </summary> class RollingDie { /// <summary> /// Random number generator /// </summary> private Random random; /// <summary> /// Number of sides that the die has /// </summary> private int sidesCount; }
Ďalej v konštruktoroch vytvoríme inštanciu triedy Random.
Upravené konštruktory budú vyzerať nasledovne:
/// <summary> /// Initializes a new 6-sided die instance /// </summary> public RollingDie() { sidesCount = 6; random = new Random(); } /// <summary> /// Initializes a new die instance /// </summary> /// <param name="sidesCount">Number of sides that the die has</param> public RollingDie(int sidesCount) { this.sidesCount = sidesCount; random = new Random(); }
Hod kockou
Teraz môžeme v triede RollingDie definovať ďalšiu metódu.
Nazveme ju Roll():
/// <summary> /// Rolls a die /// </summary> /// <returns>A number from 1 to sides count</returns> public int Roll() { return random.Next(1, sidesCount + 1); }
Metóda nám vráti náhodné číslo od jednej do počtu strán, bude
public (bude ju možné volať zvonku) 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
Next(). Tá má niekoľko preťažení:
Next()– Varianta bez parametra vráti náhodné číslo v celom rozsahu dátového typuint, konkrétne teda od-2147483648do2147483647.Next(do)– Vracia nezáporné čísla menšie než hranicado. Napríkladrandom.Next(100)vráti číslo od0do99.Next(od, do)– Vráti náhodné číslo v zadanom rozsahu, pričomoddo intervalu patrí adouž nie. Náhodné číslo od1do100by teda vrátilo preťaženierandom.Next(1, 101).
Pre naše účely sa najlepšie hodí tretie preťaženie. Dajte si pozor,
aby ste netvorili generátor náhodných čísel v metóde, ktorá má náhodné
číslo vracať – teda aby sa pre každé náhodné číslo nevytváral nový
generátor. Výsledné čísla potom takmer nie sú 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 nej potom metódu
Next() volajte.
Prekrývanie metódy
ToString()
Kocka je takmer hotová, ukážme si ešte jednu užitočnú metódu, ktorú
jej pridáme a ktorú budeme hojne používať aj vo väčšine našich
ďalších objektov. Reč je o metóde ToString(), ktorú sme už
spomenuli 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 C# funguje implicitná
konverzia, akonáhle teda budeme chcieť do konzoly vypísať číslo alebo
ktorýkoľvek iný objekt, C# 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 Print(), keď máme v C# pripravenú cestu, ako
toto riešiť. V prípade kocky nemá ToString() väčší 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:
{CSHARP_CONSOLE} RollingDie sixSided = new RollingDie(); RollingDie tenSided = new RollingDie(10); Console.WriteLine(sixSided); Console.ReadKey(); {/CSHARP_CONSOLE}{CSHARP_OOP} class RollingDie { private Random random; private int sidesCount; public RollingDie() { sidesCount = 6; random = new Random(); } public RollingDie(int sidesCount) { this.sidesCount = sidesCount; random = new Random(); } public int GetSidesCount() { return sidesCount; } public int Roll() { return random.Next(1, sidesCount + 1); } } {/CSHARP_OOP}
Do konzoly sa vypíše iba cesta k našej triede, teda
Arena.RollingDie. Metódu nemôžeme len tak definovať, pretože
je už definovaná (v ďalších lekciách zistíme prečo). Musíme ju teda
prepísať, resp. prekryť. Tým sa opäť nebudeme teraz
podrobne zaoberať, potrebné je však, aby sme už teraz vedeli
ToString() používať. Na prekrytie použijeme kľúčové slovo
override:
{CSHARP_OOP} class RollingDie { private Random random; private int sidesCount; public RollingDie() { sidesCount = 6; random = new Random(); } public RollingDie(int sidesCount) { this.sidesCount = sidesCount; random = new Random(); } public int GetSidesCount() { return sidesCount; } public int Roll() { return random.Next(1, sidesCount + 1); } /// <summary> /// Returns a textual representation of our die /// </summary> /// <returns>Textual representation of the die</returns> public override string ToString() { return String.Format("Rolling a die with {0} sides", sidesCount); } } {/CSHARP_OOP}{CSHARP_CONSOLE} RollingDie sixSided = new RollingDie(); RollingDie tenSided = new RollingDie(10); Console.WriteLine(sixSided); Console.ReadKey(); {/CSHARP_CONSOLE}
Teraz opäť skúsime do konzoly vypísať priamo inštanciu kocky.
Výstup:
Konzolová aplikácia
Rolling a die with 6 sides
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:
{CSHARP_CONSOLE} // Create instances RollingDie sixSided = new RollingDie(); RollingDie tenSided = new RollingDie(10); // Rolls the 6-sided die Console.WriteLine(sixSided); for (int i = 0; i < 10; i++) Console.Write(sixSided.Roll() + " "); // Rolls the 10-sided die Console.WriteLine("\n\n" + tenSided); for (int i = 0; i < 10; i++) Console.Write(tenSided.Roll() + " "); Console.ReadKey(); // If you run the code through our online compiler, the result // is cached, and the same numbers will keep appearing. // Any change in the code (e.g., even adding a comment) will trigger // a new compilation and thus the generation of new numbers. {/CSHARP_CONSOLE}{CSHARP_OOP} class RollingDie { private Random random; private int sidesCount; public RollingDie() { sidesCount = 6; random = new Random(); } public RollingDie(int sidesCount) { this.sidesCount = sidesCount; random = new Random(); } public int GetSidesCount() { return sidesCount; } public int Roll() { return random.Next(1, sidesCount + 1); } public override string ToString() { return String.Format("Rolling a die with {0} sides", sidesCount); } } {/CSHARP_OOP}
Výstup:
Konzolová aplikácia
Rolling a die with 6 sides
3 6 6 1 6 3 6 2 6 3
Rolling a die with 10 sides
5 9 9 2 10 4 9 3 10 5
Máme hotovú pomerne 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 opätovne používať komponenty.
V nasledujúcom cvičení, Riešené úlohy k 4.-5. lekcii OOP v C# .NET, 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é 3x (56.37 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#
