Temel sınıfın üyesine erişiliyor


118

TypeScript sitesindeki oyun alanından miras örneğine bakın:

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);

Bir satır kodu değiştirdim: içindeki uyarı Horse.move(). Oraya erişmek istiyorum super.nameama bu sadece geri dönüyor undefined. IntelliSense, onu kullanabileceğimi ve TypeScript'in iyi derlendiğini öneriyor, ancak işe yaramıyor.

Herhangi bir fikir?

Yanıtlar:


179

Çalışma örneği. Aşağıdaki notlar.

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. Adı genel bir değişkene manuel olarak atamanıza gerek yoktur. public nameYapıcı tanımında kullanmak bunu sizin için yapar.

  2. super(name)Uzmanlık sınıflarından aramanıza gerek yok .

  3. this.nameEserleri kullanmak .

Kullanımıyla ilgili notlar super.

Bu, dil spesifikasyonunun 4.9.2 bölümünde daha ayrıntılı olarak ele alınmaktadır .

'Dan miras alan sınıfların Animaldavranışı, diğer dillerdeki davranıştan farklı değildir. superÖzelleştirilmiş bir işlev ile temel sınıf işlevi arasında karışıklığı önlemek için anahtar sözcüğü belirtmeniz gerekir . Örneğin, aradıysanız move()veya this.move()özelleşmiş Snakeveya Horseişlevle ilgilenecekseniz , kullanımı super.move()açıkça temel sınıf işlevini çağırır.

Örneğin özellikleri oldukları için özelliklerle ilgili bir karışıklık yoktur. Orada arasında hiçbir fark yoktur super.nameve this.namesadece orada - this.name. Aksi takdirde, uzmanlık sınıfında veya temel sınıfta olmanıza bağlı olarak farklı adlara sahip bir At yaratabilirsiniz.


Harika cevap ve dil spesifikasyonuna referans için teşekkürler. Örneğin, temel sınıf özellik erişimcilerin neden sanallaştırılmadığına ve türetilmiş sınıftaki geçersiz kılınan erişimciler aracılığıyla erişilebilir olmadığına dair herhangi bir dokümantasyondan haberdar mısınız?
David Cuccia

Bölüm 4.8, bugüne kadar yazılan her şeyi kapsar - "nedeni budur" değil, "davranış budur" olma eğilimindedir.
Fenton

3
Teşekkürler Steve Fenton. Ayrıca burada benzer bir tartışmaya rastladım: typcript.codeplex.com/discussions/418349 . Dilde bir dengesizlik gibi görünüyor; Tahminimce, JavaScript desteği eksikliğini telafi etmek için "geçici çözüm" yardımcı yöntemlerinin aksine, yayılan JavaScript'i basit tutmaya karar verildi.
David Cuccia

1

superVe thisanahtar kelimesini hatalı kullanıyorsunuz . İşte nasıl çalıştıklarına bir örnek:

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.

Açıklama:

  1. İlk günlük çıktıları super.name, bu nesnenin prototip zincirine atıfta bulunur tom, nesnenin tomkendisi değil . Üzerinde bir name özelliği eklediğimiz için Animal.prototype, atı çıktısı alınacaktır.
  2. İkinci log çıktısı this.nameise, thisanahtar kelime tom nesnesinin kendisini ifade eder.
  3. Üçüncü günlük, moveAnimal temel sınıfının yöntemi kullanılarak günlüğe kaydedilir . Bu yöntem, sözdizimi ile Horse sınıfı taşıma yönteminden çağrılır super.move(45);. superAnahtar kelimeyi bu bağlamda kullanmak moveHayvan prototipinde bulunan prototip zincirinde bir yöntem arayacaktır .

TS'nin hala prototipleri kullandığını ve classve extendsanahtar kelimelerinin prototip kalıtım yerine sözdizimsel şeker olduğunu unutmayın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.