Les propriétés abstraites sont utiles pour les mêmes raisons que les méthodes abstraites ; une propriété en lecture seule est conceptuellement similaire à une méthode getter, donc une propriété abstraite en lecture seule est un peu comme avoir une méthode getter abstraite.
Par exemple, imaginez que vous avez une structure arborescente pour représenter des expressions : vous pourriez avoir une classe abstraite pour les expressions binaires, et pour éviter la duplication, la classe toString
peut vouloir utiliser une méthode this.op
pour le symbole approprié à utiliser dans la représentation de la chaîne (par ex. '+'
). Le code ci-dessous montre deux classes dans une hiérarchie possible :
abstract class MyBinaryExpr extends MyExpr {
constructor(readonly left: MyExpr, readonly right: MyExpr) { super(); }
abstract readonly op: string;
toString(): string {
return '(' + this.left + this.op + this.right + ')';
}
}
class MyAdd extends MyBinaryExpr {
op = '+';
compute(): number {
return this.left.compute() + this.right.compute();
}
}
Si le même code était écrit dans un langage comme Java où les propriétés ne peuvent pas être abstraites, le MyBinaryExpr
aurait probablement une méthode comme abstract String getOp()
dans le même but.
Une autre chose qui mérite d'être notée spécifiquement par rapport à Java est que dans Java, avoir des méthodes abstraites n'a de sens que parce que les appels de méthode dans Java sont distribué dynamiquement à la méthode concrète appartenant à la classe de l'objet au moment de l'exécution. Lorsqu'un code appelle une méthode abstraite, l'appel ne peut pas (en général) être lié à une implémentation concrète au moment de la compilation, la méthode concrète doit donc être sélectionnée au moment de l'exécution.
D'autre part, les accès aux champs comme obj.field
en Java sont lié statiquement à la compilation de la déclaration de champ appartenant à une classe selon le type de compilation de l'expression obj
. Une interface Java ne peut donc pas avoir de champs abstraits, car le compilateur ne saurait pas à quelle déclaration de champ réel se lier au moment de la compilation. La sémantique de Java n'autorise donc pas les champs abstraits. D'autre part, Javascript (et donc Typescript) résout tous les accès aux membres au moment de l'exécution, de sorte que même les accès aux propriétés sont liés dynamiquement. La sémantique permet donc aux interfaces d'avoir des propriétés abstraites.