Chci geek triko! Chci geek triko!
Extra 10 % bodů navíc a tričko zdarma při zadání kódu "TRIKO10"

Cvičení k 3. lekci OOP v C# .NET

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

ONEbit hosting Unicorn College 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 objektově orientovaného programování v C# .NET z minulé lekce. 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ého tutoriálu a pokuste se na to přijít.

Jednoduchý příklad

Naprogramujte aplikaci, která obsluhuje člověka. Člověk má jméno a únavu, která je zpočátku 0. Může uběhnout určitou vzdálenost a také spát určitou dobu. Běháním se jeho únava zvyšuje (1 jednotka únavy na 1 km), spaním se snižuje (10 jednotek únavy na 1 hodinu). Navrhněte třídu tak, aby se únava nikdy nemohla dostat z rozmezí 0-20 jednotek. Samozřejmě vám k tomu pomůže zapouzdření, únava určitě nebude veřejným atributem.

Program vyzkoušíte tak, že necháte člověk 3x uběhnout 10 km. Třetí uběhnutí by se nemělo povést. Když člověka necháte po druhém uběhnutí hodinu spát, zvládne i třetí běh.

Na úvod vypište instanci člověka. Definujte mu metodu ToString() tak, aby se vypsalo jeho jméno a věk.

Ukázka obrazovky programu:

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

    class Clovek
    {
    }

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

Naprogramujte za pomoci OOP generátor náhodných vět. Nechte ho vygenerovat 10 vět a tyto věty vypište do konzole.

Svůj generátor vybavte následující slovní zásobou:

  • Podměty: jednorožec, programátor, manažer, hroch, T-rex
  • Přísudky: spal, ležel, vařil, uklízel, derivoval
  • Přívlastky: modrý, velký, hubený, nejlepší, automatizovaný
  • Příslovce: rychle, s oblibou, hodně, málo, se zpožděním
  • Příslovečná určení místa: pod stolem, v lese, u babičky, v práci, na stole

Ukázka obrazovky programu:

Konzolová aplikace
velký programátor s oblibou spal u babičky
automatizovaný manažer málo uklízel v lese
hubený hroch hodně derivoval pod stolem
hubený manažer s oblibou derivoval v lese
automatizovaný jednorožec rychle vařil pod stolem
modrý T-rex s oblibou derivoval na stole
nejlepší manažer s oblibou spal u babičky
automatizovaný T-rex s oblibou vařil u babičky
automatizovaný T-rex s oblibou uklízel u babičky
hubený programátor rychle vařil v práci

    class GeneratorVet
    {
    }

Pokročilý příklad

Naprogramujte aplikaci, ve které figuruje auto a garáž. U auta evidujte SPZ a jeho barvu, u garáže evidujte jaké auto je v ní zaparkované (ne jen jeho SPZ, ale opravdu celé auto). Nechte auto s SPZ "123ABC" zaparkovat do garáže (pomocí jeho metody Zaparkuj()) a poté nechte vypsat garáž, která při svém výpisu vypíše i auto v ní zaparkované.

Ukázka obrazovky programu:

Konzolová aplikace
V garáži je auto: 123ABC

    class Auto
    {
    }
    class Garaz
    {
    }

 

Stáhnout

Staženo 1051x (127.81 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?
10 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.
Aktivity (15)

 

 

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

Avatar
Jan Kalenský:19. března 0:52

Ahoj, tady je moje řešení druhého příkladu s použitím dvojrozměrného pole.
Main:

static void Main(string[] args)
        {
            Generator generator = new Generator(10);
            Console.ReadKey();
        }

Generator:

class Generator
    {
        /// <summary>
        /// 0 - pridJmena, 1 - podJmena, 2 - prislovce, 3 - slovesa, 4 - jmenoSPred, 5 - koho
        /// </summary>
        private string[,] zasoba =
                                    {
                                        {"velký", "automatizovaný", "hubený", "modrý", "nejlepší"},
                                        {"programátor", "hroch", "manažer", "matematik", "filozof"},
                                        {"s oblibou", "málo", "hodně", "závistivě", "naschvál"},
                                        {"lízal", "uklízel", "derivoval", "smažil", "zabíjel"},
                                        {"u babičky", "v lese", "pod stolem", "v práci", "na pouti"},
                                        {"kočku", "integrál", "mobil", "strom", "kamaráda"}
                                    };

        private string[] veta = new string[6];

        private Random random = new Random();

        private string[] Veta()
        {
            for (int i = 0; i < 6; i++)
            {
                veta[i] = zasoba[i, random.Next(5)];
            }
            return veta;
        }

        public Generator(int pocet)
        {
            for (int j = 0; j < pocet; j++)
            {
                Veta();
                for (int i = 0; i < 6; i++)
                {
                    Console.Write("{0} ", veta[i]);
                }
                Console.WriteLine();
            }
        }

    }
 
Odpovědět 19. března 0:52
Avatar
Petr Koller
Člen
Avatar
Petr Koller:29. března 18:53

Zdar, moje řešení 3. příkladu.

Main:

static void Main(string[] args)
        {
            Auto trabant = new Auto("123ABC","modra");
            Garaz garaz = new Garaz(trabant.Zaparkuj());
            Console.WriteLine(garaz);
            Console.ReadKey();
        }

Auto:

class Auto
   {
       private string spz;
       private string barva;

       public Auto(string spz, string barva)
       {
           this.spz = spz;
           this.barva = barva;
       }
       public string Zaparkuj()
       {

           return VrazSPZ();
       }
       public string VrazSPZ()
       {
           return spz;
       }
   }

Garáž:

class Garaz
   {
       private string autovGarazi;
       public Garaz(string auto)
       {
           autovGarazi = auto;
       }

       public override string ToString()
       {
           return String.Format("V garáži je auto: {0}", autovGarazi);
       }
   }

Všechny připomínky beru, s OOP teprve začínám, každá rada se hodí.

 
Odpovědět 29. března 18:53
Avatar
Dušan Kovářík:14. června 4:20

Úplně si nejsem jistý mírou náhodnosti výstupu u druhého příkladu:

>

technicky nadaný programátor výtečně pařil na tribuně
tlustý kulturista výtečně hrál na kytaru na tribuně
tlustý Elon Musk výtečně hrál na kytaru ve výtahu
hezký skinhead znechuceně makal na tribuně
geniální matematik výtečně plaval na opuštěném ostrově
technicky nadaný Elon Musk elegantně pařil na tribuně
vysoký astrobiolog zoufale makal pod pípou
vysoký Elon Musk platonicky hrál na kytaru na opuštěném ostrově
tlustý matematik znechuceně počítal ovečky na tribuně
retardovaný pubertální hejsek beznadějně počítal diferenciální rovnice na opuštěném ostrově

Každopádně jsem to naprogramoval takhle:

/// <summary>
/// Třída reprezentuje generátor náhodných celých čísel od 0 po n
/// </summary>
class NahodnaCisla
{

    /// <summary>
    /// Generátor náhodných čísel
    /// </summary>
    private Random random;

    /// <summary>
    /// Vytvoří novou instanci generátoru celých čísel
    /// </summary>
    public NahodnaCisla()
    {
        random = new Random();
    }

    /// <summary>
    /// Vygeneruje náhodné číslo větší nebo rovno 0 a menší než n
    /// </summary>
    /// <returns>Číslo od 1 do počtu stěn</returns>
    public int VygenerujNahodneCislo(int n)
    {
        return random.Next(n);
    }

    /// <summary>
    /// Vrací textovou reprezentaci generátoru
    /// </summary>
    /// <returns>Textová reprezentace generátoru náhodných čísel</returns>
    public override string ToString()
    {
        return String.Format("Generátor náhodných celých čísel v rozmezí 0 až n - 1");
    }
}
class GeneratorVet
{
    private NahodnaCisla nahodnaCisla;
    private string veta;
    private string[][] elementyVety =
    {
        new string[] {"geniální", "retardovaný", "vysoký", "tlustý", "drsný",
                      "hezký", "technicky nadaný", "manuálně zručný", "nejsilnější" },
        new string[] {"programátor", "matematik", "kulturista", "skinhead", "exhibicionista",
                       "Elon Musk", "astrobiolog", "pubertální hejsek" },
        new string[] {"vášnivě", "romanticky", "platonicky", "beznadějně", "zoufale",
                      "znechuceně", "elegantně", "extrémně", "trochu", "výtečně" },
        new string[] {"pařil", "hrál na kytaru", "makal", "plaval", "počítal diferenciální rovnice",
                      "počítal ovečky"},
        new string[] {"ve výtahu", "pod lípou", "pod pípou", "na tribuně", "na opuštěném ostrově" }
    };

    public GeneratorVet()
    {
        nahodnaCisla = new NahodnaCisla();
    }

    public string VygenerujVetu()
    {
        veta = "";
        for (int i = 0; i < elementyVety.Length; i++)
        {
            veta += elementyVety[i][nahodnaCisla.VygenerujNahodneCislo(elementyVety[i].Length)] + " ";
        }
        return veta;
    }
}
class Program
{
    static void Main(string[] args)
    {
        GeneratorVet generatorVet = new GeneratorVet();
        for (int i = 0; i < 10; i++)
            Console.WriteLine(generatorVet.VygenerujVetu());
        Console.ReadKey();
    }
}

Musím zjistit více o tom, jak ty generátory pseudonáhodných čísel ve skutečnosti fungují...

 
Odpovědět 14. června 4:20
Avatar
Dušan Kovářík:15. června 0:10

Ve třetím příkladu jsem implementoval i metody pro výjezd auta z garáže.

Main:

    static void Main(string[] args)
    {
        Garaz garazElonaMuska = new Garaz();
        Console.WriteLine(garazElonaMuska);

        Auto fordModelT = new Auto("STR1905", "černá");
        Auto teslaRoadster = new Auto("SEX8888", "červená");

        fordModelT.Zaparkuj(garazElonaMuska);
        Console.WriteLine(garazElonaMuska);

        if (!teslaRoadster.Zaparkuj(garazElonaMuska))
        {
            Console.WriteLine("Elon Musk: \"Alberte, chovám k tobě hlubokou úctu, ale vyjeď laskavě s tou kraksnou z mojí garáže\"");
            Console.WriteLine("Albert Einstein: \"Jak myslíš Elone\"");
            fordModelT.Vyjed(garazElonaMuska);
            Console.WriteLine(garazElonaMuska);
        }

        teslaRoadster.Zaparkuj(garazElonaMuska);
        Console.WriteLine(garazElonaMuska);

        Console.ReadKey();
    }
}

Auto:

/// <summary>
/// Třída reprezentuje auto, které má SPZ a barvu
/// </summary>
class Auto
{
    /// <summary>
    /// Státní poznávací značka auta
    /// </summary>
    private string spz;

    /// <summary>
    /// Barva auta
    /// </summary>
    private string barva;

    /// <summary>
    /// Vytvoří instanci auta
    /// </summary>
    /// <param name="spz"></param>
    /// <param name="barva"></param>
    public Auto(string spz, string barva)
    {
        this.spz = spz;
        this.barva = barva;
    }

    /// <summary>
    /// Zaparkuje auto do garáže
    /// </summary>
    /// <param name="garaz"></param>
    /// <returns>true v případě úspěchu, false v případě neúspěchu</returns>
    public bool Zaparkuj(Garaz garaz)
    {
        if (garaz.Vjezd(this))
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    /// <summary>
    /// Nechá auto vyjet z garáže
    /// </summary>
    /// <param name="garaz"></param>
    /// <returns>true v případě úspěchu, false v případě neúspěchu</returns>
    public bool Vyjed(Garaz garaz)
    {
        if (garaz.Vyjezd(this))
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    /// <summary>
    /// Vrátí text s SPZ auta
    /// </summary>
    /// <returns>SPZ auta</returns>
    public string ZiskejSPZ()
    {
        return spz;
    }

    /// <summary>
    /// Vrátí informace o autě
    /// </summary>
    /// <returns>Text obsahující SPZ a barvu auta</returns>
    public override string ToString()
    {
        return String.Format("Auto - SPZ: {0}, barva: {1}", spz, barva);
    }
}

Garáž:

/// <summary>
/// Třída reprezentuje garáž, do které je možné zaparkovat jedno auto
/// </summary>
class Garaz
{
    /// <summary>
    /// Objekt třídy Auto, které je zaparkováno v garáži
    /// </summary>
    private Auto zaparkovaneAuto;

    /// <summary>
    /// Garáž je buď volná (true) nebo je v ní zaparkováno auto (false)
    /// </summary>
    private bool jeVolna;

    /// <summary>
    /// Vytvoří instanci třídy - novou garáž, která je volná
    /// </summary>
    public Garaz()
    {
        jeVolna = true;
    }

    /// <summary>
    /// Pokud je garáž volná, nechá do ní zaparkovat auto
    /// </summary>
    /// <param name="auto"></param>
    /// <returns>true v případě úspěšného zaparkování, false v případě neúspěchu (garáž je již obsazená)</returns>
    public bool Vjezd(Auto auto)
    {
        if (jeVolna)
        {
            zaparkovaneAuto = auto;
            jeVolna = false;
            return true;
        }
        else
        {
            return false;
        }
    }

    /// <summary>
    /// Nechá auto vyjet z garáže
    /// </summary>
    /// <returns>true v případě úspěšného výjezdu,
    /// false v případě neúspěchu (v garáži je jiné auto než požadované k výjezdu
    /// nebo je prázdná)</returns>
    public bool Vyjezd(Auto auto)
    {
        if (zaparkovaneAuto == auto)
        {
            zaparkovaneAuto = null;
            jeVolna = true;
            return true;
        }
        else
        {
            return false;
        }
    }

    /// <summary>
    /// Vrátí text s SPZ zaparkovaného auta v garáži
    /// </summary>
    /// <returns>Text s SPZ zaparkovaného auta; pokud je garáž volná, pak text s příslušným oznámením</returns>
    public override string ToString()
    {
        if (!jeVolna)
            return String.Format("V garáži je auto: {0}", zaparkovaneAuto.ZiskejSPZ());
        else
            return "Garáž je volná";
    }
}
 
Odpovědět 15. června 0:10
Avatar
Dušan Kovářík:15. června 1:11

Ahoj, tvoji otázku jsem objevil až teď, takže nevím, jestli je pro tebe ještě aktuální.
Nicméně v 1. případě se do atributu s názvem auto přiřadí parametr medody Vloz(), který se jmenuje také auto. Ten atribut i parametr jsou v podstatě proměnné, akorát to nejsou "běžné" proměnné jako např. proměnná typu int, double, string apod., ale vlastně něco jako "proměnná typu Auto". A to this je tam právě kvůli tomu stejnému názvu atributu i parametru - aby bylo jasné, co je co (this.auto je atribut objektu a auto bez this je parametr metody).

Ve 2. případě se na objektu garaz volá metoda Vloz() a to this je tam zase proto, že parametr který metodě předáváme, je právě ten objekt auto (tj. "proměnná typu Auto"), se kterým ve třídě zrovna pracujeme...Třída je vlastně jakýmsi popisem typu proměnné, který si definujeme sami. A třída kromě atributů obvykle obsahuje i metody. A v metodách jsou příkazy, které něco dělají. A pokud chceme odkázat na takovouto proměnnou, jejíž typ jsme si definovali sami (v našem případě typ Auto), zevnitř metody, která se sama nachází uvnitř definice tohoto typu, pak musíme použít klíčové slovo this. Tím vlastně jakoby říkáme "předávám ti sebe samého").

Uf, to se fakt polopatě vysvětluje blbě :) Člověk si na to musí trochu zvyknout, než to hlava pobere. Možná ještě takhle: představ si, že pracuješ s úplně normální proměnnou typu string. My zvnějšku nevidíme, co se děje "pod pokličkou", když na proměnné tohoto typu zavoláme nějakou metodu (nazvěme ji Metoda1). Prostě to napíšeme a C# to vykoná. Ale co kdybys měl možnost se podívat do nějakého skrytého kódu, který zajišťuje vykonání této metody a mohl bys ho editovat? Mohlo by se ti stát, že by se ti hodilo použít ještě nějakou jinou metodu - říkejme jí Metoda2 -, která by s tím stringem, na kterém byla zavolána Metoda1, něco udělala. Ale jak bys jí ten string předal "zevnitř" Metody1? Právě k tomuto účelu existuje to this, kterým Metoda1 říká Metodě2: "jako parametr ti předávám právě ten string, na kterém jsem byla já sama zavolána".
Když tak klidně napiš i soukromě na e-mail.

 
Odpovědět 15. června 1:11
Avatar
Ladislav Kolar:5. listopadu 22:50

Co znamená ta číslovka na výpisu z 1. cvičení? Únava to zřejmě nebude. Ještě mě napadá věk, ale v zadání se nepíše, že by člověk měl atribut věk.

 
Odpovědět 5. listopadu 22:50
Avatar
Odpovídá na Ladislav Kolar
Ladislav Kolar:6. listopadu 0:27

Odovědí mi bylo hotové řešení, skutečně se jedná o věk. Větší problém mám ale s odevzdáním 2. cvičení, kde je výstup samozřejmě náhodný a pravděpodobnost shody s předlohou prakticky nulová.

 
Odpovědět 6. listopadu 0:27
Avatar
Odpovídá na Ladislav Kolar
Ladislav Kolar:6. listopadu 0:37

Samozřejmě to prostě nechat vypsat do konzole daný text je asi možné vždy, ale tím to tak nějak celé postrádá smysl.

 
Odpovědět 6. listopadu 0:37
Avatar
David Jančík
Tým ITnetwork
Avatar
Odpovídá na Ladislav Kolar
David Jančík:6. listopadu 4:50

Testy očekávají a kontrolují dynamický výstup.

Odpovědět 6. listopadu 4:50
Čím více času dostaneš, tím méně ho máš.
Avatar
Odpovídá na David Jančík
Ladislav Kolar:7. listopadu 12:51

Aha díky, nakonec mi to na několikátý pokus prošlo (ten stejný kód). Tak nevím, v čem je chyba.

 
Odpovědět 7. listopadu 12:51
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 48. Zobrazit vše