class, pole třídy, vlastnost { get; set; }, konstruktor, metoda objektu, new, staticPostava a třídu PriseraList<T> z minulých hodin — nebo jen prohlížečPostava — plán, podle kterého se vyrábějí hrdinové.List<Postava>.Tenhle blok je jen pro vás — dětem ho nepromítejte.
| Fáze | Co se děje | Čas |
|---|---|---|
| Rozjezd | Formička a perníky, tři hrdinové na tabuli bez tříd | 10 min |
| První třída | Bloky 2–3, class + new + tečka |
20 min |
| Konstruktor | Blok 4 + ukázka 2 | 15 min |
| Metody objektu | Bloky 5–6 + ukázky 3–4 | 20 min |
static |
Blok 7 + ukázka 5 | 10 min |
| Cvičení | Děti pracují samy, vy obcházíte | 55 min |
| Závěr | Kdo chce, ukáže svou družinu | 10 min |
Dnešek je největší myšlenkový skok celého kurzu. Do dneška byl program seznam příkazů nad hromadou proměnných. Ode dneška je program parta věcí, které si pamatují svůj stav a něco umí.
Nejde o zapamatování syntaxe. Jde o to, aby dítě dokázalo říct větu: „Postava je plán. Hrdina je konkrétní kus podle toho plánu." Kdo tohle řekne vlastními slovy, tomu je dědičnost příště jasná za deset minut.
Nezačínejte kódem. Začněte formičkou na perníčky. Formička je třída, perníčky jsou objekty. Každý perníček má stejný tvar, ale jinou polevu. Formička sama se nedá sníst.
: za názvem třídy. Přijde příští hodinu
a děti by to teď jen zamlžilo.{ get; set; }) jako výchozí volbu, pole jen tam, kde je opravdu privátní.Jak pracovat se smíšenou úrovní. Cvičení 1 a 2 zvládne každý — je to opisování
s malou obměnou. Cvičení 3 je první, kde se musí přemýšlet (metoda mění stav objektu).
Cvičení 4 spojuje třídy se List<T> a je nejlepší na procvičení. Cvičení 5 je
celé kolo hry — slabším nechte jen dvě postavy místo tří.
Nejčastější zádrhel hodiny: děti napíšou třídu nad příkazy a překladač
zaječí CS8803. V C# s top-level příkazy musí být všechny třídy až úplně dole,
pod posledním příkazem. Napište to velkým písmem na tabuli hned na začátku.
Devět proměnných pro tři hrdiny. A to jsme jim zatím nedali ani zlato, ani úroveň, ani zbraň.
Zkus si představit, co se stane, když:
Číslovaná jména proměnných jsou vždycky znamení, že se něco dělá špatně. Potřebujeme způsob, jak říct: „tohle všechno patří k sobě a je to jeden hrdina".
class Postava je plán. Říká: každá postava na světě má jméno a životy.
Sama o sobě nic nedělá a nedá se z ní hrát — stejně jako se nedá sníst formička.
new Postava() vyrobí konkrétní kus podle toho plánu. Tomu kusu se říká
objekt nebo instance. Můžeš jich vyrobit kolik chceš a každý má
svoje vlastní hodnoty.
Tečka je „jeho". hrdina.Jmeno čti jako „hrdinovo jméno".
public znamená „zvenku vidět". Kdyby tam nebylo, C# by údaj schoval
a řádek hrdina.Jmeno = "Ela"; by se nepřeložil.
V programu s top-level příkazy (tak píšeme celý kurz) musí být deklarace tříd
až pod posledním příkazem. Když třídu napíšeš nahoru, dostaneš chybu
CS8803: Top-level statements must precede namespace and type declarations.
public string Jmeno { get; set; } je vlastnost (property).
Zvenku se používá úplně stejně jako pole — hrdina.Jmeno = "Ela"; —
ale uvnitř je to dvojice malých metod: get (dej hodnotu) a set (ulož hodnotu).
Tahle podoba se jmenuje automatická vlastnost. C# si sám vyrobí schovanou krabici na hodnotu a ty se o nic nestaráš.
Když potřebuješ hlídat hodnotu, rozepíšeš set ručně, jako u Zivoty.
Uvnitř set je vždycky k dispozici proměnná value — to je to, co se přiřazuje.
Math.Max(0, value) zajistí, že životy nikdy neklesnou pod nulu.
Proto se v C# skoro vždycky píšou vlastnosti, ne holá pole: až se za měsíc rozhodneš hlídat hodnotu, nemusíš přepisovat zbytek programu.
private znamená opak public — dovnitř vidí jen třída sama.
Konstruktor je metoda, která se spustí při new. Poznáš ho podle dvou věcí:
jmenuje se přesně jako třída a nemá návratový typ (není tam void ani int).
Díky němu už nejde vyrobit postavu bez jména. Tenhle řádek se nepřeloží:
Postava nekdo = new Postava(); // CS7036 — chybí argumenty
A to je dobře! Konstruktor je smlouva: „chceš postavu? Řekni mi jméno, životy a sílu, jinak ti ji nedám."
Všimni si dvojího psaní: Jmeno s velkým je vlastnost objektu, jmeno
s malým je parametr konstruktoru. Řádek Jmeno = jmeno; znamená
„ulož mi, co jsi mi předal".
Konstruktorů může být víc — liší se počtem parametrů. Ten kratší může
zavolat delší pomocí : this(...):
Postava novy = new Postava("Míra");
Console.WriteLine($"{novy.Jmeno}: {novy.Zivoty} HP, síla {novy.Sila}");
class Postava
{
public string Jmeno { get; set; }
public int Zivoty { get; set; }
public int Sila { get; set; }
public Postava(string jmeno, int zivoty, int sila)
{
Jmeno = jmeno;
Zivoty = zivoty;
Sila = sila;
}
public Postava(string jmeno) : this(jmeno, 100, 10) { }
}
Metoda uvnitř třídy vidí na svoje vlastnosti bez tečky. V Utoc je
Sila automaticky síla toho objektu, na kterém se metoda zavolala.
Když napíšeš hrdina.Utoc(sok), tak uvnitř metody:
Jmeno a Sila znamenají Elu,cil znamená Skřeta.Když napíšeš sok.Utoc(hrdina), role se prohodí. Stejný kód, jiný objekt.
Tomuhle se říká, že metoda pracuje nad instancí.
Kdybys chtěl zdůraznit „moje", můžeš psát this.Sila. Znamená to totéž
a používá se hlavně tam, kde by se jinak parametr pletl s vlastností.
Všimni si, že JeNazivu() nic nevypisuje — jen vrátí true nebo false.
Rozhodování necháváme na tom, kdo metodu volá.
Bez ToString() by se vypsalo Postava — jen název typu. Nic užitečného.
Každý objekt v C# metodu ToString() už má (zdědil ji, o tom příště).
Slovo override znamená „tuhle hotovou metodu přepíšu po svém".
Odteď se objekt umí představit sám. Funguje to všude, kde se čeká text:
Console.WriteLine(hrdina),$"...{hrdina}..." v interpolaci,string.Join(", ", druzina) u celého seznamu.Je to jedna z nejlevnějších věcí, kterou můžeš třídě přidat, a nejvíc zpřehlední výpisy. Piš ji do každé třídy, kterou vyrobíš.
Obyčejná vlastnost patří objektu. Každá postava má svoje jméno.
static patří třídě jako celku. PocetPostav existuje jednou pro
všechny postavy dohromady — proto se čte Postava.PocetPostav, ne a.PocetPostav.
Typické použití static:
MaxZivotu),const je static napevno — hodnota se nikdy nesmí změnit.
Console.WriteLine(a.PocetPostav); se nepřeloží (CS0176).
Statický údaj se čte přes jméno třídy, ne přes objekt.
Třídy jsou referenční typy. Proměnná Postava hrdina nedrží objekt, ale
odkaz na něj. Proto se po Postava b = a; mění obě proměnné zároveň —
ukazují na tentýž objekt. Dětem to dnes neříkejte teorií, ale mějte to v záloze,
až někdo objeví, že „se mu to mění na dvou místech". Krátká demonstrace stačí:
Postava a = new Postava("Ela");
Postava b = a;
b.Jmeno = "Míra";
Console.WriteLine(a.Jmeno); // Míra!
class Postava
{
public string Jmeno { get; set; }
public Postava(string jmeno)
{
Jmeno = jmeno;
}
}
struct vs. class. struct je hodnotový typ a kopíruje se. Do 15 let
to nemá smysl otevírat; pokud se někdo zeptá, řekněte „to je stejná myšlenka,
ale kopíruje se to místo sdílení".
Automatické vlastnosti nejsou magie — překladač si vyrobí skryté pole
(<Jmeno>k__BackingField). Proto je výkonnostně jedno, jestli píšete pole
nebo auto-property, a proto se doporučuje vždycky property.
null a NullReferenceException. Neinicializovaná vlastnost typu string
je null a hrdina.Jmeno.Length na ní spadne. Řešení pro děti je jednoduché:
konstruktor s parametry, který nikdy nenechá nic prázdné. Proto se ke
konstruktoru dostáváme hned ve třetím bloku, ne na konci hodiny.
record. Moderní C# má record Postava(string Jmeno, int Zivoty); —
jeden řádek místo dvaceti. Vypadá to lákavě, ale děti by pak nepochopily,
co se stalo. Ukažte to nejrychlejším jako bonus na konci hodiny, ne dřív.
Pořadí v souboru. Top-level příkazy musí předcházet deklaracím typů
(CS8803). V reálném projektu ve VS Code se tenhle problém nestane, protože
každá třída má vlastní soubor — a to je přesně to, k čemu se dostaneme
v hodině o modulech.
Pojmenování. V C# se vlastnosti a metody píšou PascalCase (Jmeno, Utoc),
parametry a lokální proměnné camelCase (jmeno, pocetKol). Trvejte na tom
od první minuty, ať si nezvyknou na python_style.
Zlato a vypiš ji.class Postava nahoru nad příkazy a přečti si chybu.Co si z toho odnést: jedna třída, dva objekty. Každý new vyrobí nový kus
s vlastní pamětí — a class je vždycky až úplně dole.
set.zlato.CS7036.MaxZivotu na 200 a zkus nastavit životy na 180.Co si z toho odnést: set je poslední obrana objektu. Ať mu zvenku pošleš
cokoliv, Math.Clamp to srovná do povoleného rozsahu a objekt zůstane platný.
Uzdrav(int kolik) a použij ji uprostřed souboje.█.Co si z toho odnést: hrdina.Utoc(skret) a skret.Utoc(hrdina) je jedna
metoda ve dvou rolích. Objekt uvnitř metody vždycky pracuje sám se sebou.
OrderByDescending).Co si z toho odnést: List<Postava> funguje úplně stejně jako List<int> —
jen místo čísel drží celé objekty. A foreach mění objekty uvnitř seznamu doopravdy,
protože seznam drží odkazy.
new Random(7) a uvidíš jiný průběh.Odmena(), která vrátí zlato podle síly.Co si z toho odnést: tohle je celý dnešek pohromadě — dvě třídy, konstruktory,
metody, List<T>, náhoda a smyčka. A hlavně: hlavní program je krátký a čitelný,
protože všechna práce je schovaná v metodách objektů.
error CS8803: Top-level statements must precede
namespace and type declarations.
Chyba číslo jedna dnešní hodiny. Třída je napsaná nad příkazy. V programu s top-level příkazy musí být pořadí vždycky takhle:
Console.WriteLine, cykly, new, …),class.Řešení je prosté: označ celý blok class ... { ... } a přesuň ho na úplný
konec souboru. Nic jiného měnit nemusíš — C# si třídu najde, i když je pod
příkazy, které ji používají.
Druhý kandidát na chybu dne je NullReferenceException. Znamená, že proměnná
typu objekt nikdy nedostala hodnotu z new, nebo že string vlastnost zůstala
prázdná. Lék je vždycky stejný — konstruktor, který všechno vyplní.
| Hláška / projev | Co to znamená | Jak to opravit |
|---|---|---|
CS8803 |
třída je nad příkazy | přesuň všechny class na konec souboru |
CS7036 |
konstruktor chce argumenty, nedostal je | new Postava("Ela", 100, 12) |
CS1061 ... does not contain a definition for ... |
překlep v názvu vlastnosti nebo metody | zkontroluj velká písmena: Jmeno, ne jmeno |
CS0122 ... is inaccessible due to its protection level |
chybí public |
dej public před vlastnost nebo metodu |
CS0176 |
statický údaj se čte přes objekt | Postava.PocetPostav, ne hrdina.PocetPostav |
CS0120 |
nestatický údaj se čte bez objektu | vyrob objekt: new Postava(...) a čti přes něj |
NullReferenceException |
proměnná je prázdná (null) |
chybí new, nebo vlastnost nikdy nedostala hodnotu |
vypíše se jen Postava |
třída nemá ToString() |
přidej public override string ToString() |
| změna u jednoho hrdiny se projeví i u druhého | obě proměnné ukazují na stejný objekt | vyrob druhý objekt vlastním new |
CS0029 Cannot implicitly convert type |
metoda má void, ale používáš návrat |
dej metodě návratový typ (int, bool, string) |
Postava se postupně rozrůstá. Piš do jednoho souboru a nech si ho
otevřený, budeš ho potřebovat i příští hodinu.
class patří úplně dolů, pod poslední příkaz.Zadání:
Vyrob první vlastní třídu a postav podle ní dva hrdiny.
- Napiš na konec souboru třídu
Postavase čtyřmi vlastnostmi💡 Poradit
Třída patří pod všechny příkazy:class Postava{public string Jmeno { get; set; }public string Povolani { get; set; }public int Zivoty { get; set; }public int Sila { get; set; }}
Bezpublicna ně zvenku neuvidíš.- Vyrob hrdinu pomocí
newa vyplň mu všechny čtyři údaje💡 Poradit
Postava hrdina = new Postava();hrdina.Jmeno = "Ela";
Tečka znamená „jeho". Pozor na velká písmena —Jmeno, nejmeno.- Vypiš hrdinovu vizitku do rámečku
💡 Poradit
Rámeček vyrobíš z opakovaného znaku:Console.WriteLine(new string('─', 34));
Údaje zarovnáš v interpolaci:Console.WriteLine($" Jméno: {hrdina.Jmeno}");- Přidej druhou postavu a vypiš vizitky obou stejnou pomocnou metodou
💡 Poradit
Metodu si napiš mezi příkazy (ne do třídy):void Vizitka(Postava p){Console.WriteLine($" {p.Jmeno} — {p.Povolani}");}
Pak stačíVizitka(hrdina);aVizitka(parta);- Přidej vlastnost
Zlatoa do vizitky dopiš bojovou hodnotu💡 Poradit
Do třídy přidejpublic int Zlato { get; set; }
Bojovou hodnotu spočítej přímo ve výpisu:$"Bojová hodnota: {p.Sila * 2 + p.Zivoty / 10}"
| Úroveň | Co má zvládnout |
|---|---|
| Minimum | Body 1–3, jedna postava a její vizitka |
| Rozšíření | Body 4–5, dvě postavy a společná pomocná metoda |
| Výzva | Přidat třetí postavu a vypsat, kdo má nejvyšší bojovou hodnotu |
Očekávaný výsledek: dvě vizitky v rámečcích, každá s jinými údaji a s vlastní bojovou hodnotou.
Kde se zaseknou:
CS8803. Čekejte to u poloviny třídy. Reagujte pořád
stejnou větou: „Kam patří třídy?" — a nechte je odpovědět „dolů".hrdina.jmeno → CS1061. Dobrá příležitost ukázat,
že VS Code jméno napovídá po napsání tečky (Ctrl+mezerník).new → Postava hrdina; a pak NullReferenceException.
Vysvětlete: „deklarace je jen cedulka, new teprve vyrobí věc."Vizitka uvnitř třídy. Někdo ji tam přirozeně napíše — a je to
vlastně lepší návrh! Pochvalte a řekněte, že přesně to uděláme ve cvičení 3.Rychlíkům zadejte třetí postavu a porovnání bojových hodnot pomocí if.
Toto je jedna z možných variant. Tvoje řešení se může lišit a to je v pořádku.
Zadání:
Zařiď, aby se žádná postava nenarodila prázdná ani se zápornými životy.
- Přidej do třídy konstruktor se čtyřmi parametry
💡 Poradit
Konstruktor se jmenuje jako třída a nemá návratový typ:public Postava(string jmeno, string povolani, int zivoty, int sila){Jmeno = jmeno;...}- Vyrob obě postavy jedním řádkem přes konstruktor
💡 Poradit
Postava hrdina = new Postava("Ela", "Strážkyně", 100, 12);
Pořadí argumentů musí sedět s pořadím parametrů. Řádkyhrdina.Jmeno = ...už nepotřebuješ a smaž je.- Přidej metodu
ToString()a vypiš postavy rovnou💡 Poradit
Do třídy:public override string ToString(){return $"{Jmeno,-8} {Povolani,-12} {Zivoty,4} HP";}
Pak stačíConsole.WriteLine(hrdina);- Změň
Zivotyna hlídanou vlastnost v rozsahu 0 ažMaxZivotu💡 Poradit
Potřebuješ soukromé pole a ručníget/set:private int zivotyUvnitr;public int Zivoty{get { return zivotyUvnitr; }set { zivotyUvnitr = Math.Clamp(value, 0, MaxZivotu); }}
A nahoru do třídypublic const int MaxZivotu = 150;- Přidej druhý konstruktor pro nováčka, který doplní výchozí hodnoty
💡 Poradit
Kratší konstruktor zavolá ten delší:public Postava(string jmeno) : this(jmeno, "Nováček", 80, 6) { }
Pak funguje inew Postava("Míra").
| Úroveň | Co má zvládnout |
|---|---|
| Minimum | Body 1–2, postavy vznikají jedním řádkem |
| Rozšíření | Body 3–4, ToString() a hlídané životy |
| Výzva | Bod 5 a k tomu ošetřit prázdné jméno (string.IsNullOrWhiteSpace) |
Očekávaný výsledek: tři postavy vypsané jedním Console.WriteLine(objekt),
životy nikdy mimo rozsah 0–150.
Kde se zaseknou:
public void Postava(...)) → C# to bere
jako obyčejnou metodu a new Postava("Ela", ...) pak hlásí CS1729.
Ukažte rozdíl vedle sebe na tabuli.set { Zivoty = value; },
vyrobí StackOverflowException. Musí tam být soukromé pole, ne vlastnost sama.override u ToString() → varování a vypíše se název typu.: this(...) se plete s dědičností. Dnes říkejte jen „tenhle konstruktor
si zavolá ten druhý". Dvojtečka za názvem třídy přijde příští hodinu.Dobrá otázka do třídy: „Proč je lepší mít konstruktor než pět řádků s tečkou?" Odpověď, ke které je chcete dovést: nejde zapomenout na údaj.
Toto je jedna z možných variant. Tvoje řešení se může lišit a to je v pořádku.
Zadání:
Přesuň chování dovnitř objektu. Postava už nebude jen údaj — bude to někdo, kdo něco umí.
- Přidej do třídy metodu
JeNazivu(), která vrátítruenebofalse💡 Poradit
Metoda uvnitř třídy vidí na vlastnosti bez tečky:public bool JeNazivu(){return Zivoty > 0;}
Nic nevypisuje — jen vrací odpověď.- Přidej metodu
Utoc(Postava cil), která sebere cíli životy💡 Poradit
public void Utoc(Postava cil){cil.Zivoty = Math.Max(0, cil.Zivoty - Sila);}Silaje moje síla,cil.Zivotyjsou jeho životy.Math.Maxzabrání zápornému stavu.- Přidej metodu
ProuzekZivotu(), která vrátí proužek z█a░💡 Poradit
Nejdřív spočítej délku plné části:int delka = Zivoty * 20 / MaxZivotu;
Pak slož text:return $"{Jmeno,-8} │{new string('█', delka).PadRight(20, '░')}│ {Zivoty,4} HP";- Nech oba soupeře bojovat ve smyčce, dokud jeden nepadne
💡 Poradit
while (hrdina.JeNazivu() && skret.JeNazivu())
Uvnitř:hrdina.Utoc(skret);a pak jen když ještě žijeif (skret.JeNazivu()) skret.Utoc(hrdina);
Přidej si pojistkukolo <= 20, ať smyčka nikdy neběží donekonečna.- Přidej lektvary a metodu
Uzdrav(), kterou hrdina použije při málo životech💡 Poradit
Do třídy přidejpublic int Lektvary { get; set; }a metodu:public bool Uzdrav(int kolik){if (Lektvary <= 0) return false;Lektvary--;Zivoty = Math.Min(MaxZivotu, Zivoty + kolik);return true;}
V souboji:if (hrdina.Zivoty < 30) hrdina.Uzdrav(25);
| Úroveň | Co má zvládnout |
|---|---|
| Minimum | Body 1–2, útok objektu na objekt funguje |
| Rozšíření | Body 3–4, proužky životů a souboj do konce |
| Výzva | Bod 5 a k tomu hlášku, když hrdinovi dojdou lektvary |
Očekávaný výsledek: souboj proběhne za několik kol, proužky se krátí a hrdina vypije lektvar přesně v okamžiku, kdy klesne pod 30 HP.
Kde se zaseknou:
Sila versus cil.Sila. Nejčastější logická chyba hodiny: dítě napíše
cil.Zivoty -= cil.Sila; a soupeř si ubere sám podle své vlastní síly.
Nechte je to spustit a ptejte se, proč jsou čísla divná — chyba se najde sama.kolo <= 20. Trvejte na ní.ProuzekZivotu. Kdo nenastaví MaxZivotu v konstruktoru,
dostane DivideByZeroException. Ukažte, že konstruktor je jediné místo,
kde se to má nastavit.JeNazivu() nic nevypisuje.
Odpověď: „rozhodování patří tomu, kdo se ptá."Rychlíkům zadejte kritický zásah: každé páté kolo dvojnásobné poškození.
Toto je jedna z možných variant. Tvoje řešení se může lišit a to je v pořádku.
Zadání:
Tři hrdinové už nebudou tři proměnné. Budou to tři objekty v jednom seznamu.
- Vyrob
List<Postava>a přidej do něj tři členy družiny💡 Poradit
List<Postava> druzina = new List<Postava>();druzina.Add(new Postava("Ela", 100, 12));
Objekt se dá vyrobit rovnou uvnitřAdd— nemusí mít vlastní proměnnou.- Vypiš celou družinu cyklem
foreacha spočítej její životy💡 Poradit
foreach (Postava clen in druzina){Console.WriteLine(clen);}
Součet:druzina.Sum(p => p.Zivoty), počet:druzina.Count.- Přidej do třídy statické počitadlo vyrobených postav
💡 Poradit
Do třídy:public static int PocetPostav = 0;
Do konstruktoru:PocetPostav++;
Čte se přes jméno třídy:Console.WriteLine(Postava.PocetPostav);- Spusť past — každému seber 25 životů a zjisti, kdo přežil
💡 Poradit
Nejdřív zraň všechny:foreach (Postava clen in druzina) clen.Zivoty = Math.Max(0, clen.Zivoty - 25);
Pak vyfiltruj živé:List<Postava> zivi = druzina.Where(p => p.JeNazivu()).ToList();- Vypiš statistiku družiny: nejsilnější, nejzraněnější a průměrná síla
💡 Poradit
druzina.OrderByDescending(p => p.Sila).First()druzina.OrderBy(p => p.Zivoty).First()druzina.Average(p => p.Sila)— výsledek zaokrouhli zápisem{prumer:F1}
| Úroveň | Co má zvládnout |
|---|---|
| Minimum | Body 1–2, družina v seznamu a její výpis |
| Rozšíření | Body 3–4, statické počitadlo a past |
| Výzva | Bod 5 a k tomu seřadit výpis družiny podle životů |
Očekávaný výsledek: družina tří postav, past vyřadí Míru (má jen 20 HP),
statistika sedí a Postava.PocetPostav odpovídá počtu volání new.
Kde se zaseknou:
druzina.PocetPostav → CS0176. Skvělá příležitost zopakovat rozdíl
mezi „patří objektu" a „patří třídě".foreach. U objektů funguje — protože seznam drží odkazy.
Kdo to zkoušel se seznamem čísel, pamatuje si opak. Tohle je nejlepší moment
celé hodiny na vysvětlení rozdílu a děti ho pochopí z příkladu, ne z teorie.Where bez ToList() → typ nesedí (CS0266). Stačí dopsat .ToList().Average vrací double — bez :F1 se vypíše šest desetinných míst.Rychlíkům zadejte, ať vyřazené členy ze seznamu skutečně odeberou pomocí
druzina.RemoveAll(p => !p.JeNazivu()); a vysvětlí, proč se mazání nesmí
dělat uvnitř foreach.
Toto je jedna z možných variant. Tvoje řešení se může lišit a to je v pořádku.
Zadání:
Poslední cvičení spojí celý dnešek: dvě třídy, kostka a celá výprava do jeskyně.
- Napiš druhou třídu
Priseras odměnou a metodouJeNazivu()💡 Poradit
Vypadá skoro stejně jakoPostava:class Prisera{public string Jmeno { get; set; }public int Zivoty { get; set; }public int Sila { get; set; }public int Odmena { get; set; }}
Nezapomeň na konstruktor se čtyřmi parametry a naToString().- Vyrob hrdinu a
List<Prisera>se třemi nestvůrami💡 Poradit
List<Prisera> bestiar = new List<Prisera>();bestiar.Add(new Prisera("Skřet", 40, 6, 15));
Pak je projdiforeacha ohlas každé setkání.- Přidej souboj s hodem kostkou
💡 Poradit
Random kostka = new Random(7);— se semínkem 7 padne vždycky totéž, dobře se to ladí.
V metodě:public void Utoc(Prisera cil, int hod)a uvnitřint poskozeni = Sila + hod;
Volání:hrdina.Utoc(nestvura, kostka.Next(1, 7));- Za každou poraženou nestvůru přidej hrdinovi zlato
💡 Poradit
Až vnitřníwhileskončí, zjisti proč:if (!hrdina.JeNazivu()) break;hrdina.Zlato += nestvura.Odmena;
A vypiš hlášku o vítězství.- Na konci vypiš bilanci výpravy a hodnocení
💡 Poradit
Poražené spočítáš takhle:int poraženo = bestiar.Count(p => !p.JeNazivu());
Hodnocení zvládneif/else ifpodle zlata, nebo ternární operátor:string znamka = zlato >= 100 ? "legenda" : "učeň";
| Úroveň | Co má zvládnout |
|---|---|
| Minimum | Body 1–2, bestiář existuje a vypíše se |
| Rozšíření | Body 3–4, souboje s kostkou a zlato za vítězství |
| Výzva | Bod 5 a k tomu +2 k síle hrdiny po každém vítězství |
Očekávaný výsledek: hrdinka projde všechny tři nestvůry (se semínkem 7 to vyjde), nasbírá 105 zlata a získá titul „legenda jeskyně".
Kde se zaseknou:
Postava.Utoc má parametr typu Prisera
a naopak. Někdo se zděsí, že to nemůže fungovat, protože Prisera je
napsaná níž. Uklidněte je: v jednom souboru na pořadí tříd nezáleží,
překladač si nejdřív přečte celý soubor.break na špatném místě. Když break chybí, hrdina pokračuje mrtvý.
Ukažte, že vnitřní while může skončit ze dvou důvodů a musíme rozlišit,
který nastal.while uvnitř foreach. Pro některé je to první dvojitá smyčka
s objekty. Pomůže nakreslit to na tabuli jako „pro každou příšeru: bojuj, dokud…".new Random() se výsledek pokaždé liší a děti
nevědí, jestli mají chybu, nebo smůlu. Při ladění trvejte na new Random(7).Závěr hodiny: nechte tři dobrovolníky promítnout bilanci své výpravy. Zeptejte se, kolik proměnných by na to potřebovali bez tříd.
Toto je jedna z možných variant. Tvoje řešení se může lišit a to je v pořádku.
Uprav svůj CsQuest tak, aby hrdina i příšery byly objekty, ne hromada proměnných.
- třída
Postavas konstruktorem, který vyplní všechny údaje,- alespoň tři metody uvnitř třídy (
Utoc,JeNazivu,Uzdrav,ProuzekZivotu— vyber si),- vlastní
ToString(), aby se postava uměla vypsat jedním řádkem,- alespoň jedna hlídaná vlastnost (životy nikdy pod nulu),
- družina nebo bestiář v
List<T>a alespoň jedna statická položka.Ulož soubor a přines ho na příští hodinu — budeme z něj stavět dál.
Tenhle úkol je vstupenka do příští hodiny. Dědičnost se nedá učit na dětech,
které nemají vlastní třídu. Kdo úkol nemá, dejte mu na začátku příští hodiny
hotovou Postava ke zkopírování — ať nezůstane mimo hru.
Na co se při kontrole dívat: ne na počet řádků, ale na to, jestli je hlavní program kratší než před hodinou. To je hlavní přínos tříd a děti to samy vidí, když si obě verze postaví vedle sebe.
Časté doma vzniklé nedorozumění: děti si myslí, že static je „lepší",
protože se to píše kratší cestou. Vysvětlete znovu: static je pro to,
co je společné všem, ne pro to, co má každý svoje.
Toto je jedna z možných variant, jak mohl úkol dopadnout. Tvoje řešení se může lišit a to je v pořádku.
Oficiální dokumentace je místo, kam se programátoři chodí podívat, když si chtějí něco ověřit nebo zjistit víc detailů. Je většinou v angličtině, ale to nevadí — zkus se orientovat podle názvu příkazu a podle ukázek kódu.
| Co jsme použili | Oficiální dokumentace | Co tam najdeš |
|---|---|---|
class |
Třídy | co je třída a jak se deklaruje |
objekty a new |
Objekty | jak vzniká instance a co se při tom děje |
{ get; set; } |
Vlastnosti | automatické i ručně psané vlastnosti |
| konstruktor | Konstruktory | více konstruktorů a : this(...) |
public / private |
Modifikátory přístupu | kdo na co zvenku vidí |
static |
Klíčové slovo static |
co patří třídě místo objektu |
const |
Konstanty | hodnoty, které se nesmí změnit |
ToString() |
Object.ToString |
jak se objekt převádí na text |
this |
Klíčové slovo this |
odkaz na sebe sama |
Math.Max, Math.Clamp |
Math |
matematické pomůcky |
List<T> |
List<T> |
seznam objektů a jeho metody |
| Top-level statements | Program bez Main |
proč musí být třídy až dole |
Stránka o vlastnostech je dnes nejužitečnější — má tam příklad ručně psaného
set s kontrolou hodnoty, což je přesně to, co děláme ve cvičení 2.
Ve VS Code funguje i zkratka: napsat do třídy prop a zmáčknout Tab.
Editor doplní celou vlastnost. Ukažte to až po tom, co si ji jednou
napíšou ručně — jinak se ji nenaučí přečíst.
Pro rychlejší studenty, kteří dokončí cvičení dřív, nebo na posledních 10–15 minut.
| Cvičení | Odkaz | Proč se hodí |
|---|---|---|
| Programování — základy | umimeinformatiku.cz | čtení cizího kódu, dnes hlavně práce s daty |
| Proměnné a výrazy | umimeinformatiku.cz | co je uvnitř proměnné po několika přiřazeních |
| Funkce a procedury | umimeinformatiku.cz | metoda, parametr a návratová hodnota — základ dnešních metod objektu |
Sekce o funkcích je dnes obzvlášť vhodná, protože metoda objektu je pořád jen funkce — jen ví, ke komu patří.
Nejlepší bonus pro rychlíky ale není online cvičení, ale otázka:
„Vymysli třídu, která s hrou nesouvisí — třeba Kniha, Pizza nebo Mobil.
Jaké má vlastnosti a co umí?" Deset minut a je hotová abstrakce,
kterou by jinak vysvětlovali půl hodiny.