super(), přepsání metody, polymorfismus, isinstancePodívej se na tři třídy vedle sebe a zkus najít, co se opakuje:
Všechny umí to samé. Liší se jen v pár detailech. Kdybys chtěl přidat metodu
uzdrav, musel bys ji napsat třikrát. A pak čtyřikrát. A pak…
Dědičnost znamená „tahle třída už umí všechno, co ten rodič, a navíc si přidá něco svého".
Drž se jednoho názvosloví celý rok:
| Termín | Význam |
|---|---|
| rodičovská / základní třída | ta obecná (Prisera) |
| odvozená / potomek | ta konkrétní (Skret) |
| dědit | automaticky převzít atributy a metody |
| přepsat metodu | napsat vlastní verzi zděděné metody |
Analogie, která funguje:
„Zvíře" je obecné. „Pes" je zvíře, které navíc štěká. Nemusíš psovi znovu vysvětlovat, že dýchá a jí — to má po zvířeti. Stačí dopsat to štěkání.
Když metoda v potomkovi není, Python ji hledá u rodiče. Když tam je, použije tu z potomka. Tomu se říká přepsání metody.
Nejdůležitější technická věc hodiny:
class Drak(Prisera):
def __init__(self, jmeno, zivoty, sila, barva):
super().__init__(jmeno, zivoty, sila) # ať to udělá rodič
self.barva = barva # a tohle je navíc
super().__init__(...)znamená „rodiči, udělej svoji část". Pak si dopíšeš, co má tvoje třída navíc.Kdybys to nezavolal, drak by neměl jméno ani životy — rodičův kód by se nespustil.
def utoc(self, cil):
poskozeni = super().utoc(cil) # udělej to, co dělá rodič
return poskozeni * 2 # a ještě to zdvojnásob
super() funguje i v obyčejných metodách:
Tady obvykle docvakne, k čemu to celé je:
bestiar = [Skret("Skřet", 30, 8), Vlk("Vlk", 20, 12), Drak("Drak", 200, 40, "rudý")]
for p in bestiar:
st.write(p.zvuk()) # každá udělá SVOJI verzi
V seznamu jsou tři různé typy příšer. Voláš na nich stejnou metodu, ale každá se zachová po svém. Ty nemusíš vědět, která je která.
To je polymorfismus: „mnoho tvarů". Jedno volání, různé chování.
Tohle je zásadní, protože to výrazně zjednoduší tvůj kód.
isinstance(s, Skret) # True
isinstance(s, Prisera) # True - Skřet JE příšera
isinstance(s, Drak) # False
Skřet je zároveň skřet i příšera. Potomek je vždycky i typem rodiče.
Používej střídmě — pokud kód potřebuje moc isinstance, měl by tam být polymorfismus.
Zapamatuj si jednoduché pravidlo:
Dědičnost použij, když platí věta „X JE Y". Skřet je příšera. ✅ Meč je předmět. ✅ Hrdina má inventář — to není dědičnost, to je atribut. ❌
Špatné použití dědičnosti dělá kód horším, ne lepším.
Všimni si, že konkrétní příšery mají
__init__bez parametrů. Samy vědí, jaké mají hodnoty. Vytvoříš je jednoduše:Skret().
abc, dekorátor @abstractmethod. Pro pokročilé žáky
je to hezké rozšíření (příšera, kterou nelze vytvořit přímo).super() v Pythonu 3 nepotřebuje argumenty. Starý zápis super(Skret, self)
uvidí děti ve starých návodech na internetu.class Skret(Prisera) je class Skret : Prisera,
super().__init__() je : base(...). Rozdíl: v Pythonu jsou všechny metody
virtuální, override se nepíše.| Chyba | Příčina | Řešení |
|---|---|---|
AttributeError: no attribute 'jmeno' |
Chybí super().__init__() |
Zavolat na začátku __init__ |
TypeError: __init__ takes 1 argument |
Špatný počet argumentů u super() |
Zkontrolovat rodičovskou hlavičku |
| Přepsaná metoda se nevolá | Překlep v názvu metody | Musí být přesně stejný název |
| Sdílený seznam mezi objekty | Seznam v těle třídy místo v __init__ |
Vytvářet v __init__ |
NameError: Prisera is not defined |
Rodič definovaný až po potomkovi | Rodiče psát nahoru |
| Dědičnost tam, kde má být atribut | „má" místo „je" | Použít kompozici |
Zadání:
- Napiš rodičovskou třídu
Priserase jménem, životy, silou a emoji- Přidej metodu
zvuk(self)vracející"..."- Vytvoř tři potomky:
Skret,Vlk,Kostlivec- V každém potomkovi zavolej
super().__init__(...)s vlastními hodnotami- Přepiš
zvuk()v každém potomkovi a vypiš je cyklem
| Úroveň | Co má zvládnout |
|---|---|
| Minimum | Body 1–3 |
| Rozšíření | Bod 4 |
| Výzva | Bod 5 + přidat čtvrtou příšeru bez úpravy zbytku kódu |
Očekávaný výsledek: tři příšery, každá vydává jiný zvuk.
Zadání:
- Přidej rodiči metodu
utoc(self)vracejícísila + hod kostkou- Ve třídě
Vlkpřepišutoctak, aby útočil dvakrát- Ve třídě
Kostlivecpřepišprijmi_poskozenina poloviční poškození- Použij v přepsaných metodách
super(), ne kopírování kódu- Otestuj: nech každou příšeru desetkrát zaútočit a vypiš průměr
| Úroveň | Co má zvládnout |
|---|---|
| Minimum | Body 1–2 |
| Rozšíření | Body 3–4 |
| Výzva | Bod 5 + přidat draka s 30% šancí na trojnásobný útok |
Očekávaný výsledek: čísla ukazují, že schopnosti opravdu fungují.
Zadání:
- Napiš rodiče
Hrdinas životy, silou, magií a metodouutoc()- Vytvoř
Bojovnik, který má víc životů a útočí silou- Vytvoř
Kouzelnik, který má míň životů a útočí magií- Vytvoř
Lupic, který má 25% šanci na dvojnásobné poškození- Nech uživatele vybrat typ hrdiny a vytvoř odpovídající objekt
| Úroveň | Co má zvládnout |
|---|---|
| Minimum | Body 1–3 |
| Rozšíření | Bod 4 |
| Výzva | Bod 5 + porovnat všechny tři v tabulce |
Očekávaný výsledek: výběr povolání vytvoří objekt s jiným chováním.
Zadání:
- Nech uživatele vybrat typ hrdiny a typ příšery
- Vytvoř oba objekty a ulož je do
session_state- Tlačítkem proveď kolo souboje — obě strany zaútočí svou metodou
- Do logu zapisuj popisy útoků, které metody vracejí
- Po vítězství přidej hrdinovi zlato příšery
| Úroveň | Co má zvládnout |
|---|---|
| Minimum | Body 1–3 |
| Rozšíření | Bod 4 |
| Výzva | Bod 5 + statistika, kolik kol souboj trval |
Očekávaný výsledek: libovolná kombinace hrdiny a příšery funguje.
Zadání:
- Převeď hrdinu na rodiče
Hrdinaa přidej tři povolání jako potomky- Vytvoř bestiář jako seznam tříd příšer
- Při výpravě náhodně vyber příšeru a proveď souboj
- Výsledek souboje zapiš do deníku včetně typu příšery
- Zobraz v postranním panelu typ hrdiny a jeho zvláštní schopnost
| Úroveň | Co má zvládnout |
|---|---|
| Minimum | Body 1–2 |
| Rozšíření | Body 3–4 |
| Výzva | Bod 5 + přidat bosse, který se objeví po deseti výpravách |
Očekávaný výsledek: hra s výběrem povolání a různorodými nepřáteli.
Přidej do bestiáře vlastní příšeru s nějakou zvláštní schopností, kterou vytvoříš přepsáním metody. Například příšera, která se po každém kole trochu uzdraví, nebo která má šanci útok úplně minout. Napiš do komentáře, kterou metodu jsi přepsal a proč.
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 se hodí, když si chceš ověřit, jak Python dědí třídy, jak funguje super() nebo kdy použít isinstance(). Je v angličtině, ale i krátké ukázky a názvy metod ti často rychle napoví.
| Co jsme použili | Oficiální dokumentace | Co tam najdeš |
|---|---|---|
| třídy a objekty | Classes | základ práce s třídami, metodami a instancemi |
| dědičnost | Inheritance | jak odvozovat třídy a přepisovat jejich chování |
super() |
super |
zavolání rodičovského konstruktoru nebo metody |
isinstance() |
isinstance |
ověření, jestli objekt patří do dané třídy |
| přepsání metod | A First Look at Classes | jak třídy skládají data a chování do společného základu |
| Cvičení | Odkaz | Proč se hodí |
|---|---|---|
| Kódování a modelování | umimeinformatiku.cz | Hierarchie a klasifikace |
| Algoritmické myšlení | umimeinformatiku.cz | Zobecňování |
| Programování v Pythonu | umimeinformatiku.cz | Struktura kódu |
| Týmovka | umimeinformatiku.cz | Společné řešení problému |