Étendre vs. implémenter une classe abstraite pure en TypeScript

supposons que j'ai une classe abstraite pure (c'est-à-dire une classe abstraite sans aucune implémentation):

abstract class A {
    abstract m(): void;
}

comme en C# et Java, je peux étendre la classe abstraite:

class B extends A {
    m(): void { }
}

Mais pas comme en C# et Java, je peux aussi œuvre la classe abstraite:

class C implements A {
    m(): void { }
}

Comment puis-classes B et C se comporter différemment? Pourquoi devrais-je choisir un contre l'autre?

(actuellement, le texte dactylographié manuel et spécification de la langue ne pas couvrir les cours abstraits.)

40
demandé sur Michael Liu 2016-03-14 17:40:18

4 réponses

implémente le mot-clé traite la classe A comme une interface, ce qui signifie C doit implémenter toutes les méthodes définies dans un, peu importe s'ils ont une implémentation ou pas en . Il n'y a pas non plus d'appels à des méthodes super dans C.

extends se comporte plus comme ce que vous attendez d'un mot clé. Vous devez implémenter seulement les méthodes abstraites, et les super appels sont disponibles / générés.

je devinez que dans le cas de méthodes abstraites, cela ne fait pas de différence. Mais vous avez rarement un classe avec seulement des méthodes abstraites, si vous le faites, il serait beaucoup mieux de simplement de le transformer en un interface.

Vous pouvez facilement le voir en regardant le code généré. J'ai fait une aire de jeux exemple ici.

49
répondu toskv 2016-03-14 14:52:08

@toskv réponse si vous étendre une classe abstraite, vous devez appeler super() dans le constructeur de la sous-classe. Si vous œuvre la classe abstraite, vous n'avez pas à appeler super() (mais vous devez implémenter toutes les méthodes déclarées dans la classe abstraite, y compris les méthodes privées).

implémenter une classe abstraite au lieu de l'étendre pourrait être utile si vous voulez créer une classe simulée pour tester sans avoir s'inquiéter des dépendances et du constructeur de la classe d'origine.

4
répondu Cory 2018-01-16 23:55:14

j'ai été amené ici parce que je me posais la même question et en lisant les réponses il m'est apparu que le choix affecterait aussi le instanceof opérateur.

étant donné qu'une classe abstraite est une valeur réelle qui est émise à JS, elle peut être utilisée pour les contrôles d'exécution lorsqu'une sous-classe l'étend.

abstract class A {}

class B extends A {}

class C implements A {}

console.log(new B() instanceof A) // true
console.log(new C() instanceof A) // false
4
répondu Tao 2018-02-15 08:30:48

dans l'exemple des extensions que vous donnez, n'ajoutez rien de nouveau à la classe. Elle est donc prolongée par rien. Bien que l'extension par rien soit dactylographié valide, il me semble que dans ce cas "instruments" serait plus approprié. Mais en fin de compte, ils sont équivalents.

0
répondu Quentin 2 2017-06-15 11:41:32