Vánoční nadílka Vánoční nadílka
Vánoční akce! Daruj lepší budoucnost blízkým nebo sobě. Až +50 % zdarma na dárkové poukazy. Více informací

Cvičení k 5.-8. lekci OOP v C# .NET

C# .NET Objektově orientované programování Cvičení k 5.-8. lekci OOP v C# .NET American English version English version

Unicorn College ONEbit hosting Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

Následující 3 cvičení vám pomohou procvičit znalosti programování v C# .NET z minulých lekcí. Ve vlastním zájmu se je pokuste vyřešit sami. Pod článkem máte pro kontrolu řešení ke stažení. Ale pozor, jakmile se na něj podíváte bez vyřešení příkladů, ztrácí pro vás cvičení smysl a nic se nenaučíte :)

Pokud si opravdu nebudete vědět rady, podívejte se raději znovu do minulých tutoriálů a pokuste se na to přijít.

Jednoduchý příklad

Angry bird

Fotografie: Mohamed Raoof.p.m / Rex features

V aplikaci vytvořte třídu Ptak s atributy:

  • hlad = výchozí hodnota 100 jednotek
  • vaha = výchozí hodnota 50 gramů

Třídě dodejte metodu Snez(), která přijímá kolik gramů potravy má pták sníst. Váha ptáka se po snědení potravy zvýší o váhu potravy a hlad se o toto množství sníží.

Následně přidejte třídu AngryPtak, který ptáka rozšiřuje o atribut vztek s výchozí hodnotou 50 a metodu Provokuj(). Tato metoda přijímá jako parametr míru provokoce, která zvýší vztek ptáka. Pokud je pták hladový, naštve se 2x rychleji (přičte se mu tedy dvojnásobek míry provokace, než kolik bylo metodě předáno). Třídy nemusí pro zjednodušení vůbec obsahovat konstruktory.

  • Nejprve ve své aplikaci vytvořte instanci ptáka a vypište ji.
  • Následně ji nechte sníst 20g potravy a opět ji vypište.
  • Dále vytvořte instanci angry ptáka a vypište ji.
  • Instanci angry ptáka provokujte s mírou provokace 5 a vypište.
  • Dále ji nechte sníst 100g potravy a opět provokujte s mírou provokace 5. Výslednou instanci opět vypište.

Ukázka obrazovky programu:

Konzolová aplikace
Jsem pták s váhou 50 a hladem 100.
Jsem pták s váhou 70 a hladem 80.
Jsem angry-pták s váhou 50 a hladem 100, míra mého vzteku je 50.
Jsem angry-pták s váhou 50 a hladem 100, míra mého vzteku je 60.
Jsem angry-pták s váhou 150 a hladem 0, míra mého vzteku je 65.

    class Ptak
    {
    }
    class AngryPtak: Ptak
    {
    }

Středně pokročilý příklad

Rozšiřte třídu Clovek z Cvičení k 3. lekci OOP v C# .NET. Pokud cvičení nemáte zakoupené, kód třídy je následující:

/// <summary>
/// Reprezentuje člověka
/// </summary>
class Clovek
{
    /// <summary>
    /// Celé jméno
    /// </summary>
    private string jmeno;
    /// <summary>
    /// Věk
    /// </summary>
    private int vek;
    /// <summary>
    /// Únava
    /// </summary>
    private int unava = 0;

    /// <summary>
    /// Inicializuje novou instanci
    /// </summary>
    /// <param name="jmeno">Celé jméno</param>
    /// <param name="vek">Věk</param>
    public Clovek(string jmeno, int vek)
    {
        this.jmeno = jmeno;
        this.vek = vek;
    }

    /// <summary>
    /// Spí danou dobu
    /// </summary>
    /// <param name="doba">Doba v hodinách</param>
    public void Spi(int doba)
    {
        unava -= doba * 10;
        if (unava < 0)
            unava = 0;
    }

    /// <summary>
    /// Uběhne danou vzdálenost
    /// </summary>
    /// <param name="vzdalenost">Vzdálenost v Km</param>
    public void Behej(int vzdalenost)
    {
        if (unava + vzdalenost <= 20)
            unava += vzdalenost;
        else
            Console.WriteLine("Jsem příliš unavený");
    }

    /// <summary>
    /// Vrátí textovou reprezentaci člověka
    /// </summary>
    /// <returns>textová reprezentace člověka</returns>
    public override string ToString()
    {
        return string.Format("{0} ({1})", jmeno, vek);
    }
}

Třídu Clovek poděďte ve třídě Javista. Javista (vím, že máme C#, ale "síšarpista" zní divně :) ) člověka rozšiřuje o atribut IDE, kde je uložen název vývojového prostředí, ve kterém programuje. Atribut se zadává spolu s dalšími atributy Javisty v konstruktoru. Javista dále disponuje metodou Programuj(), která přijímá v parametru počet řádků, která má napsat. Za každých 10 řádku přidejte jednotku únavy a zároveň únavu nenechte vzrůst nad 20 jednotek. V případě příliš vysoké únavy metoda vypíše "Jsem příliš unavený, abych programoval".

  • V aplikaci vytvořte Javistu jménem "Karel Nový" s věkem 25 let a vypište ji do konzole.
  • Karla nechte uběhnout 2x 10 km.
  • Nechte jej naprogramovat 5 řádků.
  • Dále běhat 10 km.
  • Spát 8 hodin.
  • Naprogramovat 100 řádků.

Ukázka obrazovky programu:

Konzolová aplikace
Karel Nový (25)
Jsem příliš unavený, abych programoval
Jsem příliš unavený

Třídu musíte drobně upravit, aby bylo rozšíření možné. Nezapomeňte zavolat konstruktor předka.

    class Javista: Clovek
    {
    }
    class Clovek
    {
    }

Pokročilý příklad

Vytvořte třídu Tvar, která slouží jako předek pro všechny geometrické útvary a která definuje jejich společné vlastnosti. Všechny tvary mají nějakou barvu (string), kterou lze nastavit konstruktorem.

Od této třídy následně odvoďte třídy Trojuhelnik a Obdelnik, které budou schopny spočítat svůj obsah. Hierarchie tříd je znázorněna následujícím UML diagramem:

UML diagram

K výpočtu obsahu trojúhelníku využijte Heronova vzorce.

Heronův vzorec umožňuje vypočítat obsah libovolného trojúhelníku pomocí délek jeho stran. Při výpočtu nejprve spočítáme s (malé es). Celkový obsah spočítáme pomocí tohoto s a to takto:

Heronův vzorec

S využitím těchto tříd vypočítejte obsah tohoto obrazce:

Cvičení k OOP v PHP – Strom

Ukázka obrazovky programu:

Konzolová aplikace
Obsah stromu je 492,578098794425 cm^2

    class Obdelnik: Tvar
    {
    }
    class Trojuhelnik: Tvar
    {
    }
    class Tvar
    {
    }

Třídu Tvar by bylo vhodné označit jako abstraktní, aby jazyk chápal, že slouží pouze k dědění a nemá od ní smysl vytvářet instanci (vytvořit obecný tvar nedává smysl). Jak to udělat se dozvíte dále v C# kurzu.


 

Stáhnout

Staženo 280x (264.53 kB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

 

Článek pro vás napsal David Čápka
Avatar
Jak se ti líbí článek?
9 hlasů
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor sítě se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.
Miniatura
Následující článek
Statika
Aktivity (14)

 

 

Komentáře
Zobrazit starší komentáře (13)

Avatar
Marek
Člen
Avatar
Marek:29.5.2017 18:16

Nevím, zda v UML diagramu má být, ale také mě to zmátlo, takže jsem v předkovi metodu "Obsah()" neměl.

 
Odpovědět 29.5.2017 18:16
Avatar
jersei
Člen
Avatar
jersei:20.7.2017 15:48

Napadlo mě, že by možná bylo do zadání u "pokročilého příkladu" lepší napsat "vytvořte program, který spočítá obsah libovolného obrazce složeného z obdélníků a trojúhelníků"­...Výpočet obsahu konkrétního stromu je celkem brnkačka a sám jsem se divil, že je to pokročilý příklad...teprv, když jsem se podíval na řešení, tak jsem pochopil :)

 
Odpovědět 20.7.2017 15:48
Avatar
Karel Chaloupský:5.10.2017 14:56

Tak v závilosti na komentáři od jerseie jsem to udělal tak.. abych vypocital libovolny pocet i velikost dle uzivatelova zadani a presto kdyz jsem se podival do reseni tak jsem to takhle rozhodne nemel. Chapu co se tim autor snazil rict, ale proc to delat slozite kdyz to jde jednoduse.. Dle zadani prikladu podle me nikdo nemuze pouzit reseni prikladu ktere je prilozene pod clankem.. Chtelo by to upravit zadani prikladu. Pro stourali ktery chteji hint : pole objektů.

 
Odpovědět 5.10.2017 14:56
Avatar
Ondřej Čech:9.11.2017 16:07

No, sice to úplně přesně ze zadání nevyplývá ale celou dobu se v OOP mluví o znovupoužitelnosti, dědičnosti a polymorfismu. Tže virtuální metoda ve třídě Tvar by nám měla docvaknout, že tam bude. A pak samotné řešení pomocí cyklu je krásný příklad toho výše zmíněného. Avšak k tomu je třeba naprogramovat poněkud více programů, než během této série uděláme, abychom dostali nadhled. Samozřejmě hint: - pole objektů by velice pomohl =)

 
Odpovědět 9.11.2017 16:07
Avatar
Fíla N.
Člen
Avatar
Fíla N.:29. ledna 23:09

Ahoj,
k druhému příkladu:
Nemohla by být proměnná protected string ide => private string ide , když už ji nikde nedědíme?
Díky

 
Odpovědět 29. ledna 23:09
Avatar
Odpovídá na Fíla N.
Jakub Ondrák:13. dubna 20:03

Fíla N. Ahoj, já myslím, že ano. Protected je tam asi pro případy, kdy bychom chtěli v budoucnu dále dědit. Ale to je jen můj názor :-)

 
Odpovědět  +1 13. dubna 20:03
Avatar
Dušan Kovářík:24. června 0:09

Tak jsem po přečtení zdejší diskuze v Main() deklaroval pole Tvarů:

// obrazec stromu je složen z pěti geometrických útvarů
Tvar[] elementyObrazce = new Tvar[5];
// ...jednoho obdélníku
elementyObrazce[0] = new Obdelnik("hnědá", 3, 26);
// ...a čtyř rovnoramenných trojúhelníků
for (int i = 1; i < elementyObrazce.Length; i++)
    elementyObrazce[i] = new Trojuhelnik("zelená", 25, 15, 15);

// výpočet a výpis celkového obsahu obrazce
double obsahObrazce = 0;
foreach (Tvar tvar in elementyObrazce)
    obsahObrazce += tvar.Obsah();
Console.WriteLine("Celkový obsah obrazce je {0} cm^2", obsahObrazce);

Ve třídě Tvar jsem deklaroval metodu Obsah() jako virtual a implementoval ji tak, že vrací nulu, protože se bude volat pouze v potomcích. Vím, že to jde udělat elegantněji, nicméně to si určitě přečtu v dalších lekcích, takže zatím takhle:

/// <summary>
/// Barva útvaru
/// </summary>
protected string barva;

/// <summary>
/// Inicializuje obecnou část instance konkrétního geometrického útvaru
/// </summary>
/// <param name="barva">Barva útvaru</param>
protected Tvar(string barva)
{
    this.barva = barva;
}

/// <summary>
/// Slouží pouze k přepsání (deklarace i implementace metody je dána aktuálním stavem mých neúplných znalostí v rámci postupného absolvování tutoriálu OOP v C# .net na nejlepším českém programátorském výukovém webu ITnetwork.cz)
/// </summary>
/// <returns>Obsah útvaru (v přepsaných metodách zděděných tříd)</returns>
public virtual double Obsah()
{
    return 0;
}

Třídy Obdelnik a Trojuhelnik metodu Obsah() už samozřejmě přepisují:

/// <summary>
/// Reprezentuje obdélník
/// </summary>
class Obdelnik: Tvar
{
    /// <summary>
    /// Šířka
    /// </summary>
    private double sirka;

    /// <summary>
    /// Výška
    /// </summary>
    private double vyska;

    /// <summary>
    /// Inicializuje instanci obdélníku
    /// </summary>
    /// <param name="barva">Barva</param>
    /// <param name="sirka">Šířka</param>
    /// <param name="vyska">Výška</param>
    public Obdelnik(string barva, double sirka, double vyska): base(barva)
    {
        this.sirka = sirka;
        this.vyska = vyska;
    }

    /// <summary>
    /// Vrátí obsah obdélníku
    /// </summary>
    /// <returns>Obsah obdélníku</returns>
    public override double Obsah()
    {
        return sirka * vyska;
    }
}

Kromě toho konstruktor třídy Trojuhelnik ověřuje, zda dané tři strany vůbec mohou trojúhelník tvořit.

class Trojuhelnik: Tvar
{
    /// <summary>
    /// Délka strany a
    /// </summary>
    private double a;

    /// <summary>
    /// Délka strany b
    /// </summary>
    private double b;

    /// <summary>
    /// Délka strany c
    /// </summary>
    private double c;

    /// <summary>
    /// Inicializuje instanci trojúhelníku
    /// </summary>
    /// <param name="barva"></param>
    /// <param name="a">Strana a</param>
    /// <param name="b">Strana b</param>
    /// <param name="c">Strana c</param>
    public Trojuhelnik(string barva, double a, double b, double c) : base(barva)
    {
        if (a + b > c && a + c > b && b + c > a)
        {
            this.a = a;
            this.b = b;
            this.c = c;
        }
        else
        {
            Console.WriteLine("Chyba při inicializaci objektu trojúhelník!");
            Console.WriteLine("Délky stran nemohou tvořit trojúhelník, protože není splněna trojúhelníková nerovnost.");
        }
    }

    /// <summary>
    /// Vrátí obsah trojúhelníku
    /// </summary>
    /// <returns>Obsah trojúhelníku</returns>
    public override double Obsah()
    {
        double s = (a + b + c) / 2;
        return Math.Sqrt(s * (s - a) * (s - b) * (s - c));
    }
}
Editováno 24. června 0:11
 
Odpovědět 24. června 0:09
Avatar
Michal Cikryt:22. října 14:08

Nevím, jak ostatní, ale já vidím přeponu 25 cm a odvěsnu 15cm a tedy druhá odvěsna by měla být 20cm. Nejedná se tedy o rovnoramenný trojúhelník....

 
Odpovědět  -1 22. října 14:08
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na Michal Cikryt
David Čápka:22. října 15:08

No počkej, není přepona a odvěsna jen v pravoúhlém trojúhelníku? :-`

Editováno 22. října 15:10
Odpovědět 22. října 15:08
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
Jan Křížek:3. prosince 18:18

K druhému příkladu mi není jasná jedna věc. V zadání se píše

Za každých 10 řádku přidejte jednotku únavy...

potom

  • Karla nechte uběhnout 2x 10 km.
  • Nechte jej naprogramovat 5 řádků.

Tedy těch 5 řádků by měl v pohodě napsat, protože mu nezvedne únavu, ale ve výsledku je uvedeno, že je unaven.
Mám to chápat tak, že se řádky zaokrouhlují, nebo se v tomto případě bere únava jako desetinné číslo?

 
Odpovědět 3. prosince 18:18
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 23. Zobrazit vše