Pouze tento týden sleva až 80 % na e-learning týkající se Pythonu. Zároveň využij narozeninovou akci až 80 % zdarma při nákupu e-learningu - Více informací.
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í.
Python week + discount 80

8. diel - Aréna s mágom (dedičnosť a polymorfizmus)

V minulej lekcii, Dedičnosť a polymorfizmus , sme si vysvetlili dedičnosť a polymorfizmus. Dnes máme sľúbené, že si ich vyskúšame v praxi. Bude to opäť na našej aréne, kde z bojovníka oddědíme mága. Tento C # .NET tutoriál už patrí k tým náročnejším a bude tomu tak aj u ďalších. Preto si priebežne precvičujte prácu s objektmi, skúšajte si naše cvičenia a tiež vymýšľajte nejaké svoje aplikácie, aby ste si zažili základné veci. To, že je tu prítomný celý online kurz neznamená, že ho celý naraz prečítate a pochopíte :) Snažte sa programovať priebežne.

mág
Než začneme niečo písať, zhodneme sa na tom, čo by mal mág vedieť. Mág bude fungovať rovnako, ako bojovník. Okrem života bude mať však aj manu. Spočiatku bude mana plná. V prípade plnej many môže mág vykonať magický útok, ktorý bude mať pravdepodobne vyššie damage, ako útok normálne (ale samozrejme záleží na tom, ako si ho nastavíme). Tento útok manu vybije na 0 . Každé kolo sa bude mana zvyšovať o 10 a mág bude podnikať len bežný útok. Akonáhle sa mana úplne doplní, opäť bude môcť magický útok použiť. Mana bude zobrazená grafickým ukazovateľom, rovnako ako život.

Vytvoríme teda triedu Mag.cs , zdedíme ju z Bojovnik a dodáme ju atribúty, ktoré chceme oproti bojovníkovi navyše. Bude teda vyzerať takto (opäť si ju okomentujte):

class Mag: Bojovnik
{
    private int mana;
    private int maxMana;
    private int magickyUtok;
}

V mágovi nemáme zatiaľ prístup ku všetkým premenným, pretože sú v bojovníkovi nastavené ako privátne. Musíme triedu Bojovnik ľahko upraviť. Zmeníme modifikátory private u atribútov na protected . Budeme potrebovať len kostka a jmeno , ale pokojne nastavíme ako protected všetky atribúty charakteru, pretože sa v budúcnosti môžu hodiť, keby sme sa rozhodli oddědit ďalšie typy bojovníkov. Naopak atribút zprava nie je vhodné nastavovať ako protected , pretože nesúvisí s bojovníkom, ale s nejakou vnútornou logikou triedy. Trieda teda bude vyzerať nejako takto:

protected string jmeno;
protected int zivot;
protected int maxZivot;
protected int utok;
protected int obrana;
protected Kostka kostka;
private string zprava;

...

Prejdime ku konstruktoru.

Konštruktor potomka

C # nededia konstruktory! Je to pravdepodobne z toho dôvodu, že predpokladá, že potomok bude mať navyše nejaké atribúty a pôvodné konštruktor by u neho bol na škodu. To je aj náš prípad, pretože konštruktor mága bude brať oproti tomu z bojovníka navyše 2 parametre (mana a magický útok).

Definujeme si teda konštruktor v potomkovi, ktorý berie parametre potrebné pre vytvorenie bojovníka a niekoľko parametrov navyše pre mága.

V konštruktor potomkov je nutné vždy volať konštruktor predka. Je to z toho dôvodu, že bez volania konstruktoru nemusí byť inštancie správne inicializovaná. Konštruktor predka nevoláme iba v prípade, že žiadny nemá. Náš konštruktor musia mať samozrejme všetky parametre potrebné pre predka plus tie nové, čo má navyše potomok. Niektoré potom odovzdáme predkovi a niektoré si spracujeme sami. Konštruktor predka sa vykoná pred naším konstruktoru.

VC # .NET existuje kľúčové slovo base , ktoré je podobné nami už známemu this . Na rozdiel od this , ktoré odkazuje na konkrétnu inštanciu triedy, base odkazuje na predka. My teda môžeme zavolať konštruktor predka s danými parametrami a potom vykonať navyše inicializáciu pre mága. VC # sa volanie konstruktoru predka píše do hlavičky metódy.

Konštruktor mága bude teda vyzerať takto:

public Mag(string jmeno, int zivot, int utok, int obrana, Kostka kostka, int mana, int magickyUtok): base(jmeno, zivot, utok, obrana, kostka)
{
    this.mana = mana;
    this.maxMana = mana;
    this.magickyUtok = magickyUtok;
}

Rovnako môžeme volať aj iný konštruktor v tej istej triede (nie predka), len namiesto base použijeme this .

Presuňme sa teraz do Program.cs a druhého bojovníka (Shadow) zmeňme na mága, napr. Takto:

Bojovnik gandalf = new Mag("Gandalf", 60, 15, 12, kostka, 30, 45);
Tento výukový obsah pomáhajú rozvíjať nasledujúce firmy, ktoré možno hľadajú práve teba!

Zmenu samozrejme musíme urobiť aj v riadku, kde bojovníka do arény vkladáme. Všimnite si, že mága ukladáme do premennej typu Bojovnik . Nič nám v tom nebráni, pretože bojovník je jeho predok. Rovnako tak si môžeme typ premennej zmeniť na Mag . Keď aplikáciu teraz spustíme, bude fungovať úplne rovnako, ako predtým. Mág všetko dedí z bojovníka a zatiaľ teda funguje ako bojovník.

Polymorfizmus a prepisovanie metód

Bolo by výhodné, keby objekt Arena mohol s mágom pracovať rovnako ako s bojovníkom. My už vieme, že takémuto mechanizmu hovoríme polymorfizmus. Aréna zavolá na objekte metódu Utoc() so súperom v parametri. Nestará sa o to, či bude útok vykonávať bojovník alebo mág, bude s nimi pracovať rovnako. U mága si teda prepíšeme metódu Utoc() z predka. Prepíšeme zdedenú metódu tak, aby útok pracoval s mannou, hlavička metódy však zostane rovnaká.

Aby sme mohli nejakú metódu prepísať, musí byť v predkovi označená ako virtuálny. Nehľadajte za tým žiadnu vedu, jednoducho pomocou kľúčového slova virtual C # oznámime, že si želáme, aby potomok mohol túto metódu prepísať. Hlavičku metódy v Bojovnik.cs teda zmeníme na:

public virtual void Utoc(Bojovnik souper)

Keď sme pri metódach, budeme ešte určite používať metódu NastavZpravu() , tá je však privátne. Označme ju ako protected :

protected void NastavZpravu(string zprava)

Pri návrhu bojovníka sme samozrejme mali myslieť na to, že sa z neho bude dediť a už označiť vhodné atribúty a metódy ako protected , prípadne metódy ako virtuálne. Kľúčovým slovom virtual je označená metóda, ktorú možno v potomkovi prepísať, inak to nie je možné. V tutoriále k bojovníkovi som vás tým však nechcel zbytočne zaťažovať, preto musíme modifikátory zmeniť až teraz, kedy im rozumieme * :)

Metóda Utoc() v bojovníkovi bude teda public virtual . Teraz sa vráťme do potomka a poďme ju prepísať. Metódu normálne definujeme v Mag.cs tak, ako sme zvyknutí. Za modifikátorom public však ešte použijeme kľúčové slovo override , ktoré značí, že si sme vedomí toho, že sa metóda zdedila, ale prajeme si zmeniť jej správanie.

public override void Utoc(Bojovnik souper)

Podobne sme prepisovali metódu ToString() u našich objektov. Každý objekt v C # je totiž odděděný od System.Object , ktorý obsahuje 4 metódy, jedna z nich je aj ToString() . Pri jej implementácii teda musíme použiť override .

Správanie metódy Utoc() nebude nijako zložité. Podľa hodnoty many buď vykonáme bežný útok alebo útok magický. Hodnotu many potom buď zvýšime o 10 alebo naopak znížime na 0 v prípade magického útoku.

public override void Utoc(Bojovnik souper)
{
    int uder = 0;
    // Mana nie je naplnená
    if (mana < maxMana)
    {
        mana += 10;
        if (mana > maxMana)
            mana = maxMana;
        uder = utok + kostka.hod();
        NastavZpravu(String.Format("{0} útočí s úderem za {1} hp", jmeno, uder));
    }
    else // Magický útok
    {
        uder = magickyUtok + kostka.hod();
        NastavZpravu(String.Format("{0} použil mágiu za {1} hp", jmeno, uder));
        mana = 0;
    }
    souper.BranSe(uder);
}

Kód je asi zrozumiteľný. Všimnite si obmedzenia many na maxMana , môže sa nám totiž stať, že túto hodnotu presiahne, keď ju zvyšujeme o 10. Keď sa nad kódom zamyslíme, tak útok vyššie v podstate vykonáva pôvodnej metóda Utoc() . Iste by bolo prínosné zavolať podobu metódy na predkovi namiesto toho, aby sme správanie odpisovali. K tomu opäť použijeme base :

    public override void Utoc(Bojovnik souper)
    {
        // Mana nie je naplnená
        if (mana < maxMana)
        {
        mana += 10;
        if (mana > maxMana)
            mana = maxMana;
        base.Utoc(souper);
        }
        else // Magický útok
        {
            int uder = magickyUtok + kostka.hod();
            NastavZpravu(String.Format("{0} použil mágiu za {1} hp", jmeno, uder));
            souper.BranSe(uder);
            mana = 0;
        }
    }
    class Bojovnik
    {
        protected string jmeno;
        protected int zivot;
        protected int maxZivot;
        protected int utok;
        protected int obrana;
        protected Kostka kostka;
        private string zprava;

        public Bojovnik(string jmeno, int zivot, int utok, int obrana, Kostka kostka)
        {
        this.jmeno = jmeno;
        this.zivot = zivot;
        this.maxZivot = zivot;
        this.utok = utok;
        this.obrana = obrana;
        this.kostka = kostka;
    }

        public bool Nazivu()
        {
        return (zivot > 0);
        }

        public string GrafickyZivot()
    {
        string s = "[";
        int celkem = 20;
        double pocet = Math.Round(((double)zivot / maxZivot) * celkem);
        if ((pocet == 0) && (Nazivu()))
            pocet = 1;
        for (int i = 0; i < pocet; i++)
            s += "#";
        s = s.PadRight(celkem + 1);
        s += "]";
        return s;
        }

        public virtual void Utoc(Bojovnik souper)
        {
        int uder = utok + kostka.hod();
        NastavZpravu(String.Format("{0} útočia s úderom za {1} hp", jmeno, uder));
        souper.BranSe(uder);
        }

        public void BranSe(int uder)
        {
        int zraneni = uder - (obrana + kostka.hod());
        if (zraneni > 0)
        {
            zivot -= zraneni;
            zprava = String.Format("{0} utrpel poškodenie {1} hp", jmeno, zraneni);
            if (zivot <= 0)
            {
            zivot = 0;
            zprava += " a zomrel";
            }

        } else
        zprava = String.Format("{0} odrazil útok", jmeno);
                NastavZpravu(zprava);
        }

        protected void NastavZpravu(string zprava)
        {
        this.zprava = zprava;
        }

        public string VratPosledniZpravu()
        {
        return zprava;
        }

        public override string ToString()
        {
        return jmeno;
        }

    }
using System.Threading;

    class Arena
    {
        private Bojovnik bojovnik1;
        private Bojovnik bojovnik2;
        private Kostka kostka;

        public Arena(Bojovnik bojovnik1, Bojovnik bojovnik2, Kostka kostka)
        {
        this.bojovnik1 = bojovnik1;
        this.bojovnik2 = bojovnik2;
        this.kostka = kostka;
        }

        private void Vykresli()
        {
        Console.Clear();
        Console.WriteLine("-------------- Aréna -------------- \n");
        Console.WriteLine("Zdravie bojovníkov: \n");
        Console.WriteLine("{0} {1}", bojovnik1, bojovnik1.GrafickyZivot());
        Console.WriteLine("{0} {1}", bojovnik2, bojovnik2.GrafickyZivot());
        }

        private void VypisZpravu(string zprava)
        {
        Console.WriteLine(zprava);
        Thread.Sleep(500);
        }

        public void Zapas()
        {
        // pôvodné poradie
        Bojovnik b1 = bojovnik1;
        Bojovnik b2 = bojovnik2;
        Console.WriteLine("Vitajte v aréne!");
        Console.WriteLine("Dnes sa stretnú {0} s {1}! \n", bojovnik1, bojovnik2);
        // prehodenie bojovníkov
        bool zacinaBojovnik2 = (kostka.hod() <= kostka.VratPocetSten() / 2);
        if (zacinaBojovnik2)
        {
            b1 = bojovnik2;
            b2 = bojovnik1;
        }
        Console.WriteLine("Začínať bude bojovník {0}! \nZápas môže začať...", b1);
        Console.ReadKey();
        // cyklus s bojom
        while (b1.Nazivu() && b2.Nazivu())
        {
            b1.Utoc(b2);
            Vykresli();
            VypisZpravu(b1.VratPosledniZpravu()); // správa o útoku
            VypisZpravu(b2.VratPosledniZpravu()); // správa o obrane
            if (b2.Nazivu())
            {
            b2.Utoc(b1);
            Vykresli();
            VypisZpravu(b2.VratPosledniZpravu()); // správa o útoku
            VypisZpravu(b1.VratPosledniZpravu()); // správa o obrane
            }
            Console.WriteLine();
        }
    }

    }

Opäť vidíme, ako môžeme znovupoužívat kód. S dedičnosťou je spojené naozaj mnoho techník, ako si ušetriť prácu. V našom prípade to ušetrí niekoľko riadkov, ale u väčšieho projektu by to mohlo mať obrovský význam.

Aplikácia teraz funguje tak, ako má.

Konzolová aplikácia
-------------- Aréna --------------

Zdravie bojovníkov:

Zalgoren [#############       ]
Gandalf [#################   ]
Gandalf použil mágiu za 52 hp
Zalgoren utrpel poškodenie 36 hp

Aréna nás však neinformuje o mane mága, poďme to napraviť. Pridáme mágovi verejnú metódu GrafickaMana() , ktorá bude obdobne ako u života vracať string s grafickým ukazovateľom many.

Aby sme nemuseli logiku so zložením ukazovatele písať dvakrát, upravíme metódu GrafickyZivot() v Bojovnik.cs . Pripomeňme si, ako vyzerá:

public string GrafickyZivot()
{
    string s = "[";
    int celkem = 20;
    double pocet = Math.Round(((double)zivot / maxZivot) * celkem);
    if ((pocet == 0) && (Nazivu()))
        pocet = 1;
    for (int i = 0; i < pocet; i++)
        s += "#";
    s = s.PadRight(celkem + 1);
    s += "]";
    return s;
}

Vidíme, že nie je výnimkou premenných zivot a maxZivot na živote nijako závislá. Metódu premenujeme na GrafickyUkazatel() a dáme ju 2 parametre: aktuálnu hodnotu a maximálnu hodnotu. Premenné zivot a maxZivot v tele metódy potom nahradíme za aktualni a maximalni . Modifikátor bude protected , aby sme metódu mohli v potomkovi použiť:

protected string GrafickyUkazatel(int aktualni, int maximalni)
{
    string s = "[";
    int celkem = 20;
    double pocet = Math.Round(((double)aktualni / maximalni) * celkem);
    if ((pocet == 0) && (Nazivu()))
        pocet = 1;
    for (int i = 0; i < pocet; i++)
        s += "#";
    s = s.PadRight(celkem + 1);
    s += "]";
    return s;
}

Metódu GrafickyZivot() v Bojovnik.cs naimplementujeme znovu, bude nám v nej stačiť jediný riadok a to zavolanie metódy GrafickyUkazatel() s príslušnými parametrami:

public string GrafickyZivot()
{
    return GrafickyUkazatel(zivot, maxZivot);
}

Určite som mohol v tutoriálu s bojovníkom urobiť metódu GrafickyUkazatel() rovno. Chcel som však, aby sme si ukázali, ako sa rieši prípady, keď potrebujeme vykonať podobnú funkčnosť viackrát. S takouto parametrizáciou sa v praxi budete stretávať často, pretože nikdy presne nevieme, čo budeme v budúcnosti od nášho programu požadovať.

Teraz môžeme vykresľovať ukazovateľ tak, ako sa nám to hodí. Presuňme sa do Mag.cs a naimplementujme metódu GrafickaMana() :

public string GrafickaMana()
{
    return GrafickyUkazatel(mana, maxMana);
}

Jednoduché, že? Teraz je mág hotový, zostáva len naučiť arénu zobrazovať manu v prípade, že je bojovník mág. Presuňme sa teda do Arena.cs .

Rozpoznanie typu objektu

Keďže sa nám teraz vykreslenie bojovníka skomplikovalo, urobíme si na neho samostatnú metódu VypisBojovnika() , jej parametrom bude daná inštancie bojovníka:

private void VypisBojovnika(Bojovnik b)
{
    Console.WriteLine(b);
    Console.Write("Zivot: ");
    Console.WriteLine(b.GrafickyZivot());
}

Teraz poďme reagovať na to, či je bojovník mág. Minule sme si povedali, že k tomu slúži operátor is :

private void VypisBojovnika(Bojovnik b)
{
    Console.WriteLine(b);
    Console.Write("Život: ");
    Console.WriteLine(b.GrafickyZivot());
    if (b is Mag)
    {
        Console.Write("Mana:  ");
        Console.WriteLine(((Mag)b).GrafickaMana());
    }
}

Bojovníka sme museli na mága pretypovať, aby sme sa k metóde GrafickaMana() dostali. Samotný Bojovnik ju totiž nemá. To by sme mali, VypisBojovnika() budeme volať v metóde Vykresli() , ktorá bude vyzerať takto:

    private void Vykresli()
    {
        Console.Clear();
        Console.WriteLine("-------------- Aréna -------------- \n");
        Console.WriteLine("Bojovníci: \n");
        VypisBojovnika(bojovnik1);
        Console.WriteLine();
        VypisBojovnika(bojovnik2);
        Console.WriteLine();
    }
    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.Next(1, pocetSten + 1);
    }

    public override string ToString()
    {
        return String.Format("Kocka s {0} stenami", pocetSten);
    }
    }
    class Bojovnik
    {
    protected string jmeno;
    protected int zivot;
    protected int maxZivot;
    protected int utok;
    protected int obrana;
    protected Kostka kostka;
    private string zprava;

    public Bojovnik(string jmeno, int zivot, int utok, int obrana, Kostka kostka)
    {
        this.jmeno = jmeno;
        this.zivot = zivot;
        this.maxZivot = zivot;
        this.utok = utok;
        this.obrana = obrana;
        this.kostka = kostka;
    }

    public bool Nazivu()
    {
        return (zivot > 0);
    }

    protected string GrafickyUkazatel(int aktualni, int maximalni)
    {
        string s = "[";
        int celkem = 20;
        double pocet = Math.Round(((double)aktualni / maximalni) * celkem);
        if ((pocet == 0) && (Nazivu()))
        pocet = 1;
        for (int i = 0; i < pocet; i++)
        s += "#";
        s = s.PadRight(celkem + 1);
        s += "]";
        return s;
    }

    public string GrafickyZivot()
    {
        return GrafickyUkazatel(zivot, maxZivot);
    }

    public virtual void Utoc(Bojovnik souper)
    {
        int uder = utok + kostka.hod();
        NastavZpravu(String.Format("{0} útočia s úderom za {1} hp", jmeno, uder));
        souper.BranSe(uder);
    }

    public void BranSe(int uder)
    {
        int zraneni = uder - (obrana + kostka.hod());
        if (zraneni > 0)
        {
        zivot -= zraneni;
        zprava = String.Format("{0} utrpel poškodenie {1} hp", jmeno, zraneni);
        if (zivot <= 0)
        {
            zivot = 0;
            zprava += " a zemřel";
        }

        } else
        zprava = String.Format("{0} odrazil útok", jmeno);
        NastavZpravu(zprava);
    }

    protected void NastavZpravu(string zprava)
    {
        this.zprava = zprava;
    }

    public string VratPosledniZpravu()
    {
        return zprava;
    }

    public override string ToString()
    {
        return jmeno;
    }
    }
    class Mag: Bojovnik
    {
    private int mana;
    private int maxMana;
    private int magickyUtok;

    public Mag(string jmeno, int zivot, int utok, int obrana, Kostka kostka, int mana, int magickyUtok): base(jmeno, zivot, utok, obrana, kostka)
    {
        this.mana = mana;
        this.maxMana = mana;
        this.magickyUtok = magickyUtok;
    }

    public string GrafickaMana()
    {
        return GrafickyUkazatel(mana, maxMana);
    }

    public override void Utoc(Bojovnik souper)
    {
        // Mana nie je naplnená
        if (mana < maxMana)
        {
        mana += 10;
        if (mana > maxMana)
            mana = maxMana;
        base.Utoc(souper);
        }
        else // Magický útok
        {
        int uder = magickyUtok + kostka.hod();
        NastavZpravu(String.Format("{0} použil mágiu za {1} hp", jmeno, uder));
        souper.BranSe(uder);
        mana = 0;
        }
    }
    }

Hotovo :)

Konzolová aplikácia
-------------- Aréna --------------

Bojovníci:

Zalgoren
Život: [##########          ]

Gandalf
Život: [#####               ]
Mana: [#############       ]

Zalgoren útočia s úderom za 28 hp

Aplikáciu ešte môžeme dodať krajší vzhľad, vložil som ASCIIart nadpis Aréna, ktorý som vytvoril touto aplikáciou: http://patorjk.com/software/taag . Navyše som zafarbil ukazovatele pomocou farby pozadia a popredia. Metódu k vykreslenie ukazovatele som upravil tak, aby vykreslovala plný obdĺžnik miesto # (ten napíšete pomocou Alt + 2 1 9). Výsledok môže vyzerať takto:

Konzolová aplikácia
                __    ____  ____  _  _    __
               /__\  (  _ \( ___)( \( )  /__\
              /(__)\  )   / )__)  )  (  /(__)\
             (__)(__)(_)\_)(____)(_)\_)(__)(__)
Bojovníci:

Zalgoren
Život: ████████████████████

Gandalf
Život: ████████████████████
Mana:   ███████████████████

Gandalf použil mágiu za 48 hp
Zalgoren utrpel poškodenie 33 hp

Kód máte v prílohe. Ak ste niečomu nerozumeli, skúste si článok prečítať viackrát alebo pomalšie, sú to dôležité praktiky. V budúcej lekcii, Riešené úlohy k 5.-8. lekciu OOP v C # .NET , si vysvetlíme pojem statika.

V nasledujúcom cvičení, Riešené úlohy k 5.-8. lekciu 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é 3044x (40.04 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C#

 

Predchádzajúci článok
Dedičnosť a polymorfizmus
Všetky články v sekcii
Objektovo orientované programovanie v C #
Preskočiť článok
(neodporúčame)
Riešené úlohy k 5.-8. lekciu OOP v C # .NET
Článok pre vás napísal David Čápka
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
David je zakladatelem ITnetwork a programování se profesionálně věnuje 13 let. Má rád Nirvanu, sushi 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

 

 

Komentáre

Avatar
Josef Pospíšil:11.10.2019 7:47

Když jsem procházel publikaci od Pavla Boreho : C# bez předchozích znalostí, tak tam žádné odkazování na konstruktor předka v podobě base nebylo. Je to tedy nutné psát vždy, nebo je to starší věc a dnes už se nepoužívá, nebo jsem to jen nějak nepochopil? děkuji

 
Odpovedať
11.10.2019 7:47
Avatar
Hans
Člen
Avatar
Odpovedá na Josef Pospíšil
Hans:11.10.2019 8:43

Není to nutné psát, pokud je konstruktor předka bezparametrický, jinak ano.

 
Odpovedať
11.10.2019 8:43
Avatar
David H.
Člen
Avatar
David H.:14.4.2020 23:35

Díky za článek. ;-)

 
Odpovedať
14.4.2020 23:35
Avatar
Robin Blažek:8.5.2020 16:17

Parádní článek a celkově celá série lekcí s arénou :)

 
Odpovedať
8.5.2020 16:17
Avatar
Bohumír Bednařík:27.7.2020 17:31

Ta funkce Nazivu byla jen ukázková (pokud si dobře vzpomínám na předchozí lekce). Tvoje řešení je samozřejmě univerzálnější.

Editované 27.7.2020 17:33
 
Odpovedať
27.7.2020 17:31
Tento výukový obsah pomáhajú rozvíjať nasledujúce firmy, ktoré možno hľadajú práve teba!
Avatar
Petr Jadrníček:20.10.2020 20:49

Nefunguje mi nastaveni Tridy Bojovnik jako predek tridy Mag

class Mag: Bojovnik
    {
        private int mana;
        private int maxMana;
        private int MagickyUtok;
    }

    public Mag(string jmeno, int zivot, int utok, int obrana, Kostka kostka, int mana, int MagickyUtok): base(jmeno, zivot, utok, obrana, kostka)
    {
        this.mana = mana;
        this.maxMana = mana;
        this.MagickyUtok = mana;
    }

Nazvy argumentů jsou stále šedé.
Hlasi mi to tuto chybu:
Chyba CS7036 Není dán žádný argument, který by odpovídal požadovanému formálnímu parametru jmeno v Bojovnik.Bojov­nik(string, int, int, int, Kostka).

Můžete mi, prosím, objasnit, co mám špatně?

Protože jinak je tento kurz bez chyby a dost mi pomohl. Tak bych se nechtěl zastavit na této části.
Děkuji

 
Odpovedať
20.10.2020 20:49
Avatar
popo49
Člen
Avatar
Odpovedá na Petr Jadrníček
popo49:12.1.2021 16:37

Chyba CS7036 Není dán žádný argument, který by odpovídal požadovanému formálnímu parametru jmeno v Bojovnik.Bojov­nik(string, int, int, int, Kostka <

Tuto chybu to vypíše pokud při vytváření konstruktoru Mag se neodkážu na konstruktor předka pomoci base.
Chybu budeš mít nejspíš již v tom předkovi což je Bojovnik. Mrkni na jeho konstruktor zda odpovídá tomuto:

public Bojovnik(string jmeno, int zivot, int utok, int obrana, Kostka kostka)
{
    this.jmeno = jmeno;
    this.zivot = zivot;
    this.maxZivot = zivot;
    this.utok = utok;
    this.obrana = obrana;
    this.kostka = kostka;
}
 
Odpovedať
12.1.2021 16:37
Avatar
Odpovedá na popo49
Lubomír Mitáš:26.8.2021 16:09

Mám stejný problém. Konstrukotor ve třídě Bojovník mám přesně podle tvého vzoru.

 
Odpovedať
26.8.2021 16:09
Avatar
Odpovedá na Lubomír Mitáš
Lubomír Mitáš:26.8.2021 16:18

Už jsem na to přišel. Stejně jako tazatel jsem konstruktor třídy Mag měl mimo třídu. Konstruktor jsem musel hodit do složených závorek třídy Mag:

namespace Arena
{
    class Mag: Bojovnik
    {
        private int mana;
        private int maxMana;
        private int magickyUtok;

        public Mag(string jmeno, int zivot, int utok, int obrana, Kostka kostka, int mana, int magickyUtok) : base(jmeno, zivot, utok, obrana, kostka)
        {
            this.mana = mana;
            this.maxMana = mana;
            this.magickyUtok = magickyUtok;
        }
    }


}
 
Odpovedať
26.8.2021 16:18
Avatar
Tomáš Sobota:22. júna 20:33

Ahoj, mám malý dotaz. Ten private atribut zprava z třídy Bojovník ten potomek Mag opravdu zdědí ?(a jen není vidět a není přímo přístupný - jen přes tu metodu předka)?

 
Odpovedať
22. júna 20:33
Robíme čo je v našich silách, aby bola tunajšia diskusia čo najkvalitnejšia. Preto do nej tiež môžu prispievať len registrovaní členovia. Pre zapojenie sa do diskusie sa zaloguj. Ak ešte nemáš účet, zaregistruj sa, je to zadarmo.

Zatiaľ nikto nevložil komentár - buď prvý!