typescript - Přístup k členu základní třídy
Podívejte se na příklad dědičnosti z playgroundu na stránkách TypeScriptu:
class Animal {
public name;
constructor(name) {
this.name = name;
}
move(meters) {
alert(this.name + " moved " + meters + "m.");
}
}
class Snake extends Animal {
constructor(name) {
super(name);
}
move() {
alert("Slithering...");
super.move(5);
}
}
class Horse extends Animal {
constructor(name) {
super(name);
}
move() {
alert(super.name + " is Galloping...");
super.move(45);
}
}
var sam = new Snake("Sammy the Python");
var tom: Animal = new Horse("Tommy the Palomino");
sam.move();
tom.move(34);
Změnil jsem jeden řádek kódu: upozornění v Horse.move(). Tam chci přistoupit k super.name, ale to vrací jen undefined. IntelliSense naznačuje, že jej mohu použít a TypeScript se přeloží bez problémů, ale nefunguje to.
Máte nějaké nápady?
Odpověď č. 1
Pracující příklad. Poznámky níže.
class Animal {
constructor(public name) {
}
move(meters) {
alert(this.name + " moved " + meters + "m.");
}
}
class Snake extends Animal {
move() {
alert(this.name + " is Slithering...");
super.move(5);
}
}
class Horse extends Animal {
move() {
alert(this.name + " is Galloping...");
super.move(45);
}
}
var sam = new Snake("Sammy the Python");
var tom: Animal = new Horse("Tommy the Palomino");
sam.move();
tom.move(34);
Nemusíte ručně přiřazovat název veřejné proměnné. Použití
public namev definici konstruktoru to udělá za vás.Nemusíte volat
super(name)z specializovaných tříd.Použití
this.namefunguje.
Poznámky k použití super.
Toto je podrobněji rozebráno v části 4.9.2 specifikace jazyka.
Chování tříd dědících z Animal se nijak neliší od chování v jiných jazycích. Je nutné specifikovat klíčové slovo super, abyste předešli záměně mezi specializovanou funkcí a funkcí základní třídy. Například pokud byste zavolali move() nebo this.move(), jednalo by se o specializovanou funkci Snake nebo Horse, takže použití super.move() výslovně volá funkci základní třídy.
Nedochází k žádnému zmatku ohledně vlastností, protože jsou to vlastnosti instance. Není žádný rozdíl mezi super.name a this.name - existuje pouze this.name. Jinak byste mohli vytvořit koně, který by měl různá jména v závislosti na tom, zda jste ve specializované třídě nebo v základní třídě.
Odpověď č. 2
Používáte klíčová slova super a this nesprávně. Níže je příklad, který ukazuje jejich správné použití.
class Animal {
public name: string;
constructor(name: string) {
this.name = name;
}
move(meters: number) {
console.log(this.name + " moved " + meters + "m.");
}
}
class Horse extends Animal {
move() {
console.log(super.name + " is Galloping...");
console.log(this.name + " is Galloping...");
super.move(45);
}
}
var tom: Animal = new Horse("Tommy the Palomino");
Animal.prototype.name = 'horseee';
tom.move(34);
// Outputs:
// horseee is Galloping...
// Tommy the Palomino is Galloping...
// Tommy the Palomino moved 45m.
Vysvětlení:
První zaznamenává dynamickou hodnotu pro
super.name, za kterou následuje statická řetězcová hodnota"is Galloping...". Klíčové slovothisodkazuje na "prototype chain" objektutom, a nikoli na samotný objekttom. Protože jsme přidali vlastnost name naAnimal.prototype, bude vypsáno horse.Druhý výpis protokolu zobrazí
this.name, klíčové slovothisodkazuje na samotný objekt tom.Třetí záznam je zaznamenán pomocí metody
movezákladní třídy Animal. Tato metoda je volána z metody move třídy Horse se syntaxísuper.move(45);. Použití klíčového slovasuperv tomto kontextu bude hledat metodumovev řetězci prototypů, která je nalezena na prototypu Animal.
Pamatujte, že TS stále používá pod kapotou prototypy a klíčová slova class a extends jsou jen syntaktickým cukrem pro prototypové dědičnosti.
