Вызов переопределенного метода из суперкласса в typescript

Когда я вызываю переопределенный метод из конструктора суперкласса, я не могу правильно получить значение свойства подкласса.

Пример

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
    }
}

Я хотел бы знать, как правильно переопределять функции в typescript.

Ответы

Ответ 1

Порядок выполнения:

  • A конструктор
  • B конструктор

Назначение происходит в конструкторе B после A constructor- _super -has:

function B() {
    _super.apply(this, arguments);   // MyvirtualMethod called in here
    this.testString = "Test String"; // testString assigned here
}

Итак, происходит следующее:

var b = new B();     // undefined
b.MyvirtualMethod(); // "Test String"

Вам нужно будет изменить свой код, чтобы справиться с этим. Например, вызвав конструктор this.MyvirtualMethod() in B, создав метод factory для создания объекта, а затем выполнив эту функцию или передав строку в конструктор A и получив какой-то способ... множество возможностей.

Ответ 2

Ключ вызывает родительский метод, используя 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"

Попробуйте здесь

Ответ 3

Если вы хотите, чтобы суперкласс вызывал функцию из подкласса, самым чистым способом является определение абстрактного шаблона, таким образом, вы явно знаете, что метод существует где-то и должен быть переопределен подклассом.

Это как пример, обычно вы не вызываете вспомогательный метод внутри конструктора, поскольку дополнительный экземпляр еще не инициализирован... (причина, по которой у вас есть "undefined" в вашем примере вопроса)

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();

Протестируйте его Here

И если вам нравится @Max, вы действительно хотите избежать реализации абстрактного метода во всем мире, просто избавитесь от него. Я не рекомендую этот подход, потому что вы можете забыть, что вы переопределяете метод.

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();

Попробуйте Здесь