Vyhledávání na webu

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);
  1. Nemusíte ručně přiřazovat název veřejné proměnné. Použití public name v definici konstruktoru to udělá za vás.

  2. Nemusíte volat super(name) z specializovaných tříd.

  3. Použití this.name funguje.

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í:

  1. První zaznamenává dynamickou hodnotu pro super.name, za kterou následuje statická řetězcová hodnota "is Galloping...". Klíčové slovo this odkazuje na "prototype chain" objektu tom, a nikoli na samotný objekt tom. Protože jsme přidali vlastnost name na Animal.prototype, bude vypsáno horse.

  2. Druhý výpis protokolu zobrazí this.name, klíčové slovo this odkazuje na samotný objekt tom.

  3. Třetí záznam je zaznamenán pomocí metody move zá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 slova super v tomto kontextu bude hledat metodu move v ř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.

Související články