typescript 从打字稿中的超类调用重写的方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30819663/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 06:41:28  来源:igfitidea点击:

Call an overridden method from super class in typescript

ooptypescripttypescript1.4

提问by Sency

When I'm calling an overridden method from the super class constructor, I cannot get a value of a sub class property correctly.

当我从超类构造函数调用重写的方法时,我无法正确获取子类属性的值。

example

例子

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

I would like to know how to correctly override functions in typescript.

我想知道如何正确覆盖打字稿中的函数。

采纳答案by David Sherret

The order of execution is:

执行顺序为:

  1. A's constructor
  2. B's constructor
  1. A的构造函数
  2. B的构造函数

The assignment occurs in B's constructor after A's constructor—_super—has been called:

赋值发生在B的构造函数中,在A的构造函数_super— — 被调用之后:

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

So the following happens:

所以会发生以下情况:

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

You will need to change your code to deal with this. For example, by calling this.MyvirtualMethod()in B's constructor, by creating a factory method to create the object and then execute the function, or by passing the string into A's constructor and working that out somehow... there's lots of possibilities.

您将需要更改代码来处理此问题。例如,通过调用this.MyvirtualMethod()inB的构造函数,通过创建工厂方法来创建对象然后执行函数,或者通过将字符串传递到A的构造函数并以某种方式解决……有很多可能性。

回答by Flavien Volken

The key is calling the parent's method using super.methodName();

关键是使用 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"

Try it here

在这里试试

回答by Flavien Volken

If you want a super class to call a function from a subclass, the cleanest way is to define an abstract pattern, in this manner you explicitly know the method exists somewhere and must be overridden by a subclass.

如果您希望超类从子类调用函数,最简洁的方法是定义抽象模式,通过这种方式,您明确知道该方法存在于某处并且必须被子类覆盖。

This is as an example, normally you do not call a sub method within the constructor as the sub instance is not initialized yet… (reason why you have an "undefined" in your question's example)

这是一个例子,通常您不会在构造函数中调用子方法,因为子实例尚未初始化......(原因是您的问题示例中有“未定义”)

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

Test it Here

在这里测试

And if like @Max you really want to avoid implementing the abstract method everywhere, just get rid of it. I don't recommend this approach because you might forget you are overriding the method.

如果像@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();

Try it Here

在这里试试