Lorsque j'appelle une méthode substituée à partir du constructeur de la super classe, je ne peux pas obtenir correctement la valeur d'une propriété de la sous-classe.
exemple
class A
{
constructor()
{
this.MyvirtualMethod();
}
protected MyvirtualMethod(): void
{
}
}
class B extends A
{
private testString: string = "Test String";
public MyvirtualMethod(): void
{
alert(this.testString); // This becomes undefined
}
}
Je voudrais savoir comment remplacer correctement les fonctions dans TypeScript.
L'ordre d'exécution est:
A
B
L'affectation a lieu dans le constructeur de B
après que le constructeur de A
- _super
- a été appelé:
function B() {
_super.apply(this, arguments); // MyvirtualMethod called in here
this.testString = "Test String"; // testString assigned here
}
Donc, ce qui suit se produit:
var b = new B(); // undefined
b.MyvirtualMethod(); // "Test String"
Vous devrez changer votre code pour gérer cela. Par exemple, en appelant this.MyvirtualMethod()
dans le constructeur de B
, en créant une méthode fabrique pour créer l'objet puis exécuter la fonction, ou en passant la chaîne à A
Le constructeur et le travail en quelque sorte ... il y a beaucoup de possibilités.
La clé appelle la méthode du parent en utilisant super.methodName ();
class A {
// A protected method
protected doStuff()
{
alert("Called from A");
}
// Expose the protected method as a public function
public callDoStuff()
{
this.doStuff();
}
}
class B extends A {
// Override the protected method
protected doStuff()
{
// If we want we can still explicitly call the initial method
super.doStuff();
alert("Called from B");
}
}
var a = new A();
a.callDoStuff(); // Will only alert "Called from A"
var b = new B()
b.callDoStuff(); // Will alert "Called from A" then "Called from B"
Si vous souhaitez qu'une super-classe appelle une fonction d'une sous-classe, la méthode la plus propre consiste à définir un motif abstrait. De cette manière, vous savez explicitement que la méthode existe quelque part et doit être remplacée par une sous-classe.
Ceci est un exemple, normalement, vous n'appelez pas de méthode secondaire dans le constructeur, car la sous-instance n'est pas encore initialisée ... (raison pour laquelle vous avez un "non défini" dans l'exemple de votre question)
abstract class A {
// The abstract method the subclass will have to call
protected abstract doStuff():void;
constructor(){
alert("Super class A constructed, calling now 'doStuff'")
this.doStuff();
}
}
class B extends A{
// Define here the abstract method
protected doStuff()
{
alert("Submethod called");
}
}
var b = new B();
Testez-le ici
Et si, comme @Max, vous voulez vraiment éviter d'implémenter la méthode abstraite partout, supprimez-la simplement. Je ne recommande pas cette approche car vous pourriez oublier que vous substituez la méthode.
abstract class A {
constructor() {
alert("Super class A constructed, calling now 'doStuff'")
this.doStuff();
}
// The fallback method the subclass will call if not overridden
protected doStuff(): void {
alert("Default doStuff");
};
}
class B extends A {
// Override doStuff()
protected doStuff() {
alert("Submethod called");
}
}
class C extends A {
// No doStuff() overriding, fallback on A.doStuff()
}
var b = new B();
var c = new C();
Essayez-le ici