web-dev-qa-db-fra.com

Appeler une méthode substituée à partir de la super classe en texte dactylographié

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.

42
Sency

L'ordre d'exécution est:

  1. Le constructeur de A
  2. Le constructeur de 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.

17
David Sherret

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"

essayez ici

70
Flavien Volken

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

8
Flavien Volken