Přepsání metod
Boss zdědil od třídy Prisera metodu popis, takže se popíše jako každá příšera: Drak (300 životů). Boss by ale měl říct i to, v jaké je fázi. Odvozená třída může napsat vlastní verzi metody svého rodiče. Tomu se říká přepsání metody (anglicky override):
class Prisera {
jmeno: string;
zivoty: number;
constructor(jmeno: string, zivoty: number) {
this.jmeno = jmeno;
this.zivoty = zivoty;
}
popis(): string {
return `${this.jmeno} (${this.zivoty} životů)`;
}
}
class Boss extends Prisera {
faze: number = 1;
override popis(): string {
return `${super.popis()}, fáze ${this.faze}`;
}
}
const prisery: Prisera[] = [new Prisera("Skřet", 30), new Boss("Drak", 300)];
for (const prisera of prisery) {
console.log(prisera.popis());
}Vypíše:
Skřet (30 životů)
Drak (300 životů), fáze 1Nové jsou tu tři věci:
- Metoda ve třídě
Bossse jmenuje stejně jako ta ve tříděPrisera, a tak ji u bosse nahradí. Která verze se spustí, záleží na objektu, ne na typu proměnné: v cyklu jepriserapro TypeScript typuPrisera, ale druhý objekt je boss, a proto se spustí jeho vlastnípopis. super.popis()zavolá verzi rodiče. Boss nemusí opakovat, jak se příšery popisují: vezme jejich text a přidá k němu fázi. (Pozor:this.popis()by zavolalo metodu bosse samotnou, ta by zase volala sama sebe, a tak pořád dokola, dokud program neskončí chybouRangeError: Maximum call stack size exceeded.)- Klíčové slovo
overrideříká: „Tahle metoda nahrazuje metodu rodiče.“ Je nepovinné, ale díky němu vás TypeScript může zkontrolovat.
Proč override pomáhá. Bez něj překlep v názvu nic nenahradí, jen přidá novou metodu:
class Prisera {
jmeno: string;
zivoty: number;
constructor(jmeno: string, zivoty: number) {
this.jmeno = jmeno;
this.zivoty = zivoty;
}
popis(): string {
return `${this.jmeno} (${this.zivoty} životů)`;
}
}
class Boss extends Prisera {
faze: number = 1;
popsi(): string {
return `${this.jmeno} (${this.zivoty} životů), fáze ${this.faze}`;
}
}
const prisery: Prisera[] = [new Prisera("Skřet", 30), new Boss("Drak", 300)];
for (const prisera of prisery) {
console.log(prisera.popis());
}Vypíše:
Skřet (30 životů)
Drak (300 životů)Metoda bosse se nikdy nezavolá a nic vám neřekne proč. Napište override popsi(): string a TypeScript chybu najde:
main.ts(18,14): error TS4117: This member cannot have an 'override' modifier because it is not declared in the base class 'Prisera'. Did you mean 'popis'?Přepsaná metoda musí také odpovídat metodě rodiče: musí jít zavolat se stejnými argumenty a vrátit hodnotu typu, který vrací metoda rodiče. Kdyby popis bosse vracel číslo, TypeScript by ohlásil Property 'popis' in type 'Boss' is not assignable to the same property in base type 'Prisera'. (TS2416). Proto může boss zastoupit příšeru kdekoli: všechno, co jde udělat s příšerou, jde udělat i s bossem.
Jak psát:
Pokyny
Drak by se měl popsat i se silou svého ohně, ale program vypíše jen Rudý drak (280 životů). Před drakovu metodu napište override. TypeScript pak chybu najde. Opravte ji, aby program vypsal:
Skřet (10 životů)
Rudý drak (280 životů), oheň 40Drakova metoda opakuje, jak se popisují příšery. Pro tuto část místo toho použijte super.popis(). Program vypíše totéž.
Draci mají silné šupiny, a tak ztrácejí jen polovinu toho, co ostatní příšery. Přepište ve třídě Drak metodu ztratZivoty (s override) tak, aby zavolala verzi rodiče s polovičním počtem. Program vypíše:
Skřet (10 životů)
Rudý drak (290 životů), oheň 40Začněte programovat zdarma
8/9