J'essaie d'implémenter une méthode dans une super classe qui devrait être disponible pour utilisation, mais non modifiable, dans les sous-classes. Considère ceci:
export abstract class BaseClass {
universalBehavior(): void {
doStuff(); // Do some universal stuff the same way in all sub classes
specializedBehavior(); // Delegate specialized stuff to sub classes
}
protected abstract specializedBehavior(): void;
}
Mon intention serait que toute sous-classe de BaseClass soit non seulement libre d'omettre l'implémentation de universalBehavior()
, mais ne serait même pas autorisée à fournir une implémentation. N'est-ce pas (encore) possible en TypeScript? Intellisense se plaint lorsque j'omets l'implémentation dans mes sous-classes. Le mieux que je puisse faire, c'est ceci:
export class SubClass extends BaseClass {
universalBehavior(): void {
super.universalBehavior();
}
specializedBehavior(): void {
// sub class' implementation
}
}
Évidemment, cela pose problème car je dois m'assurer qu'aucune sous-classe n'implémente jamais universalBehavior()
avec autre chose qu'un appel à super.universalBehavior()
.
Non, au moment d'écrire ces lignes, il n'y en a pas. Il existe une proposition pour un tel mot-clé qui est toujours à l'étude, mais qui peut ou non être implémentée.
Voir:
Exemple de piratage d'implémentation de 'méthode scellée' en tant que propriété en lecture seule de type fonction qui génère une erreur de compilation lors d'une tentative de substitution dans une classe étendue:
abstract class BaseClass {
protected element: JQuery<HTMLElement>;
constructor(element: JQuery<HTMLElement>) {
this.element = element;
}
readonly public dispose = (): void => {
this.element.remove();
}
}
class MyClass extends BaseClass {
constructor(element: JQuery<HTMLElement>) {
super(element);
}
public dispose(): void { } // Compiler error: "Property 'dispose' in type 'MyClass' is not assignable to the same property in base type 'BaseClass'"
}
TypeScript 2.0 prend en charge les classes "finales" en utilisant un constructeur privé:
class A {
private constructor(){}
}
class B extends A{} //Cannot extend a class 'A'. Class constructor is marked as private.ts(2675)
// I use this workaround:
export default class CreateHandler extends BaseHandler {
// final prop used as method
public readonly create = (blueprint: Blueprint): Response<Record> => {
return blueprint.create();
};
// normal method
public store(blueprint: Blueprint): Response<Record> {
return this.response(blueprint.create());
}
}