Add a C# course with a side-by-side code runner.

Each lesson explains a topic and runs the edited program next to the text through the local .NET SDK.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
pepaskopec-blip 2026-10-11 14:37:14 +02:00
commit 333085ee53
86 changed files with 2482 additions and 5 deletions

View file

@ -0,0 +1,4 @@
---
nazev: Class and object
popis: Your own type and one concrete piece of it.
---

View file

@ -0,0 +1,40 @@
---
id: cs-3-trida
nazev: Třída a objekt
popis: Vlastní typ a jeho konkrétní kus.
---
# Výklad
## Třída
*návod*
- class Zak popisuje, co žák má: jméno a věk.
- new Zak() vytvoří objekt, jeden konkrétní kus.
- Dva new jsou dva objekty. Změna jednoho druhý nemění.
> Tip: Třída sama o sobě není žák. Je to popis.
## Pole objektu
*tečka*
- z.Jmeno se čte a zapisuje přes tečku.
- Na začátek dáme veřejná pole, ať je vidět, komu patří.
- Později je schováme za vlastnost.
> Tip: Vytvořte druhého žáka a vypište obě jména.
# Kód
```
Zak z = new Zak();
z.Jmeno = "Anna";
z.Vek = 17;
Console.WriteLine($"{z.Jmeno}, {z.Vek}");
class Zak
{
public string Jmeno;
public int Vek;
}
```

View file

@ -0,0 +1,4 @@
---
nazev: Constructor
popis: A method that fills the object immediately.
---

View file

@ -0,0 +1,44 @@
---
id: cs-3-konstruktor
nazev: Konstruktor
popis: Metoda, která objekt hned naplní.
---
# Výklad
## Jméno třídy
*new Zak*
- Konstruktor se jmenuje jako třída a nemá návratový typ.
- new Zak("Anna", 17) ho zavolá.
- Prázdný new Zak() přestane fungovat, jakmile napíšete vlastní konstruktor.
> Tip: Hodnoty patří do new, ne až na další řádky.
## this
*tento objekt*
- this.Jmeno je pole objektu. Jmeno bez this by v konstruktoru byl parametr.
- Když se jmenují stejně, this je nutný.
- Mimo konstruktor this často není potřeba.
> Tip: Přidejte do výpisu věk z konstruktoru.
# Kód
```
Zak z = new Zak("Anna", 17);
Console.WriteLine($"{z.Jmeno}, {z.Vek}");
class Zak
{
public string Jmeno;
public int Vek;
public Zak(string jmeno, int vek)
{
Jmeno = jmeno;
Vek = vek;
}
}
```

View file

@ -0,0 +1,4 @@
---
nazev: Properties
popis: get and set instead of a bare field.
---

View file

@ -0,0 +1,50 @@
---
id: cs-3-vlastnosti
nazev: Vlastnosti
popis: get a set místo holého pole.
---
# Výklad
## get a set
*tečka zůstává*
- public string Jmeno { get; set; } se zvenku používá jako pole.
- Uvnitř může set odmítnout špatnou hodnotu.
- get hodnotu vrátí, set ji uloží.
> Tip: Zápis z.Vek = -1 může set zarazit, holé pole ne.
## Kontrola
*set*
- V příkladu set u věku záporné číslo neuloží.
- get pořád vrátí poslední platnou hodnotu.
- Tak se objekt nepokazí zvenku.
> Tip: Zkuste z.Vek = -3 a vypište věk. Zůstane 17.
# Kód
```
Zak z = new Zak("Anna", 17);
z.Vek = -3;
Console.WriteLine(z.Vek);
class Zak
{
public string Jmeno { get; set; }
private int vek;
public int Vek
{
get { return vek; }
set { if (value >= 0) vek = value; }
}
public Zak(string jmeno, int vek)
{
Jmeno = jmeno;
Vek = vek;
}
}
```

View file

@ -0,0 +1,4 @@
---
nazev: Encapsulation
popis: Private data and public methods.
---

View file

@ -0,0 +1,49 @@
---
id: cs-3-zapouzdreni
nazev: Zapouzdření
popis: Soukromá data a veřejné metody.
---
# Výklad
## private
*schované*
- private pole vidí jen kód té třídy.
- public metoda je dveře, kterými se s objektem mluví.
- Zvenku z.penize nenapíšete. Zavoláte Pridej.
> Tip: Když je vše public, kdokoli rozbije pravidla objektu.
## Metoda
*Pridej*
- Pridej přičte a vrátí nový stav.
- Záporný vklad lze v metodě odmítnout.
- Výpis stavu jde přes Kolik, ne přes pole.
> Tip: Zkuste Pridej(-10). Stav se nemá zmenšit.
# Kód
```
Pokladna p = new Pokladna();
p.Pridej(50);
p.Pridej(-10);
Console.WriteLine(p.Kolik());
class Pokladna
{
private int penize;
public void Pridej(int castka)
{
if (castka > 0) penize = penize + castka;
}
public int Kolik()
{
return penize;
}
}
```

View file

@ -0,0 +1,4 @@
---
nazev: Inheritance
popis: A new class takes over a finished one.
---

View file

@ -0,0 +1,52 @@
---
id: cs-3-dedicnost
nazev: Dědičnost
popis: Nová třída převezme hotovou.
---
# Výklad
## base
*: Zak*
- class Student : Zak znamená, že student je žák a má něco navíc.
- Dostane Jmeno a Vek, aniž by se psaly znovu.
- base(...) zavolá konstruktor předka.
> Tip: Student umí to, co Zak, a ještě obor.
## Je
*typ*
- Student lze uložit do proměnné Zak. Pořád je to student.
- Opačně žák bez oboru studentem není.
- Na specialitu sáhnete, až když máte původní typ.
> Tip: Vypište i obor. Patří studentovi, ne obecnému žákovi.
# Kód
```
Student s = new Student("Eva", 18, "informatika");
Console.WriteLine($"{s.Jmeno}, {s.Obor}");
class Zak
{
public string Jmeno { get; set; }
public int Vek { get; set; }
public Zak(string jmeno, int vek)
{
Jmeno = jmeno;
Vek = vek;
}
}
class Student : Zak
{
public string Obor { get; set; }
public Student(string jmeno, int vek, string obor) : base(jmeno, vek)
{
Obor = obor;
}
}
```

View file

@ -0,0 +1,4 @@
---
nazev: Polymorphism
popis: The same call, a different answer from the child.
---

View file

@ -0,0 +1,50 @@
---
id: cs-3-polymorfismus
nazev: Polymorfismus
popis: Stejné volání, jiná odpověď potomka.
---
# Výklad
## virtual a override
*přepsání*
- virtual u předka dovolí potomkovi metodu vyměnit.
- override u potomka řekne, že jde o tu samou metodu.
- Bez virtual by potomek jen schoval jméno a přes typ předka by se volala stará verze.
> Tip: Proměnná je Zvire, objekt je Pes. Zavolá se štěk, ne obecné zvíře.
## Seznam
*víc tvarů*
- Do pole Zvire lze dát psa i kočku.
- foreach volá Zvuk a každý objekt odpoví po svém.
- Nové zvíře přidáte třídou, ne úpravou smyčky.
> Tip: Přidejte do pole kočku a třetí řádek výstupu bude mňau.
# Kód
```
Zvire[] zvirata = { new Pes(), new Kocka() };
foreach (Zvire z in zvirata)
{
Console.WriteLine(z.Zvuk());
}
class Zvire
{
public virtual string Zvuk() { return "..."; }
}
class Pes : Zvire
{
public override string Zvuk() { return "haf"; }
}
class Kocka : Zvire
{
public override string Zvuk() { return "mňau"; }
}
```

View file

@ -0,0 +1,4 @@
---
nazev: Interface
popis: A contract: which methods a type must have.
---

View file

@ -0,0 +1,50 @@
---
id: cs-3-rozhrani
nazev: Rozhraní
popis: Smlouva: které metody typ musí mít.
---
# Výklad
## interface
*I*
- interface nemá hotový kód, jen hlavičky metod.
- class Pes : IMluvici slíbí, že Mluv napíše.
- Jedna třída může splnit víc rozhraní. Dědit může jen jednu třídu.
> Tip: Jméno rozhraní se často píše s I na začátku: IMluvici.
## Společný typ
*seznam*
- Proměnná typu rozhraní udrží kohokoli, kdo smlouvu splnil.
- Pes a Radio nemají společného předka, ale oba umí Mluv.
- Smyčka jim rozumí přes smlouvu, ne přes původ.
> Tip: Rozhraní neříká, jak metoda funguje. To napíše až třída.
# Kód
```
IMluvici[] veci = { new Pes(), new Radio() };
foreach (IMluvici v in veci)
{
Console.WriteLine(v.Mluv());
}
interface IMluvici
{
string Mluv();
}
class Pes : IMluvici
{
public string Mluv() { return "haf"; }
}
class Radio : IMluvici
{
public string Mluv() { return "hudba"; }
}
```

View file

@ -0,0 +1,4 @@
---
nazev: Enum
popis: A fixed list of named values.
---

View file

@ -0,0 +1,50 @@
---
id: cs-3-enum
nazev: Výčet
popis: Pevný seznam pojmenovaných hodnot.
---
# Výklad
## enum
*Den*
- enum Den { Po, Ut, St } jsou tři pojmenované hodnoty.
- Místo magického čísla 1 píšete Den.Po.
- Překladač nepustí hodnotu, která ve výčtu není.
> Tip: Čísla 0, 1, 2 by za měsíc nikdo nepřečetl. Jména ano.
## switch
*přes výčet*
- switch na enum má case pro každou hodnotu.
- Když přidáte čtvrtek a zapomenete case, překlad na to v novém zápisu upozorní.
- Výčet je typ. Není to string.
> Tip: Změňte dnes na Den.St.
# Kód
```
Den dnes = Den.Po;
switch (dnes)
{
case Den.Po:
Console.WriteLine("pondělí");
break;
case Den.Ut:
Console.WriteLine("úterý");
break;
default:
Console.WriteLine("jiný den");
break;
}
enum Den
{
Po,
Ut,
St
}
```