Вызов переопределенного метода из суперкласса в 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();
Попробуйте Здесь