Úkol polymorfismus

3. Řešení úkolu

Třída Zvíře

namespace polymorfismus_cviceni.Models
{
    public abstract class Zvire //Z abstraktní třídy nemůžeme vytvářet instanci
    {
        public string Jmeno { get; set; } = "";    //Vytvoření vlastnosti Jmeno
        public abstract string VydejZvuk();   //Abstraktní metoda - potomci ji musejí přepsat
        public string VydejZvuk(int pocetOpakovani) //Přetížená metoda - využívá parametr
        {
            string zvuk = VydejZvuk(); //Získáme základní zvuk
            string vysledek = "";
 
            for (int i = 0; i < pocetOpakovani; i++)    //Zvuk zopakujeme tolikrát, kolik je v parametru
            {
                vysledek += zvuk + " ";
            }
 
            return vysledek.Trim(); //Vrátíme řetězec, .Trim() odstraní mezery na začátku a na konci textu
        }
    }
}
    

Třída Zvíře je definována jako abstract (abstraktní), což znamená, že z ní nelze přímo vytvářet instance (nemůžeme napsat new Zvire()). Vlastnost Jméno je společná pro všechny potomky. Ve třídě jsou definovány dvě verze metody VydejZvuk(). První je definovaná jako abstract – nemá žádné tělo a slouží jako povinný předpis, který musejí potomci přepsat. Druhá je přetížená metoda, která přijímá parametr pocetOpakovani. Tato metoda má své tělo a definuje společnou logiku: zavolá základní zvuk, který dodá konkrétní potomek a pomocí cyklu ho zopakuje.


Třídy Kočka, Pes, Koza

namespace polymorfismus_cviceni.Models
{
    public class Kocka:Zvire    //Třída kočka je potomek třídy Zvíře
    {
        public override string VydejZvuk()  //Přepisuje původní metodu VydejZvuk
        {
            return "Mňau";
        } 
    }
}
namespace polymorfismus_cviceni.Models
{
    public class Pes : Zvire    //Třída pes je potomek třídy Zvíře
    {
        public override string VydejZvuk()  //Přepisuje původní metodu VydejZvuk
        {
            return "Haf";
        }
    }
}
namespace polymorfismus_cviceni.Models
{
    public class Koza : Zvire    //Třída koza je potomek třídy Zvíře
    {
        public override string VydejZvuk()  //Přepisuje původní metodu VydejZvuk
        {
            return "Méé";
        }
    }
 
}

Pomocí dvojtečky : určujeme, že třídy Kočka, Pes a Koza jsou potomky třídy Zvíře. Protože dědí z abstraktní třídy, musejí pomocí klíčového slova override přepsat abstraktní metodu VydejZvuk. Každá třída tak definuje své vlastní chování a vrací specifický zvuk ('Mňau', 'Haf' a 'Méé').


Razor komponenta

@page "/"
 
<PageTitle>Polymorfismus</PageTitle>
 
<h1>Polymorfismus</h1>
 
<p>Všechna zvířata jsou v jednom seznamu typu <strong>List&lt;Zvire&gt;</strong>.</p>
 
<table class="table">
    <!--Tvorba tabulky pro výpis seznamu-->
    <thead>
        <tr>
            <th>Jméno</th>
            <th>Zvuk</th>
            <th>Zvuk (Přetížená metoda)</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var zvire in seznamZvirat)    //Uloží každou položku (objekt - Pes, Kočka...) ze seznamu do proměnné zvíře
        {
            <tr>
                <td>@zvire.Jmeno</td>
                <td>@zvire.VydejZvuk()</td> <!--I když pracujeme s obecným typem - zvire, spouštíme metodu konkrétního objektu - Pes, Kočka...-->
                <td>@zvire.VydejZvuk(3)</td> <!--Volání přetížené metody s parametrem 3-->
            </tr>
        }
    </tbody>
</table>
 
@code{
    private List<Models.Zvire> seznamZvirat = new List<Models.Zvire>();  //Vytváříme seznam, který umí držet cokoliv, co je "Zvire"
 
    protected override void OnInitialized()         //Metoda, která proběhne při načtení okna
    {
        seznamZvirat.Add(new Models.Pes { Jmeno = "Azor" });    //Vytvoření instancí jednotlivých zvířat a následné přidání do seznamu
        seznamZvirat.Add(new Models.Kocka { Jmeno = "Mourek" });
        seznamZvirat.Add(new Models.Koza { Jmeno = "Líza" });
    }
}

V části @code se vytváří seznamZvirat deklarovaný jako seznam objektů typu Zvíře (List<Zvire>). Při inicializaci se do tohoto seznamu přidávají konkrétní instance potomků (Pes, Kočka, Koza). V HTML části je vytvořena tabulka, která pomocí cyklu prochází tento seznam. Při prvním volání metody VydejZvuk() se pomocí polymorfismu automaticky vypíše zvuk odpovídající konkrétnímu zvířeti. Při volání metody VydejZvuk(3) s parametrem funguje přetížení metod – zavolá se metoda definovaná v rodičovské třídě, která přijme číslo a zajistí zopakování tohoto zvuku.