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

Sen*_*ncy 48 oop typescript typescript1.4

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

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
    }
}
Run Code Online (Sandbox Code Playgroud)

我想知道如何正确覆盖typescript中的函数.

Fla*_*ken 77

关键是使用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"
Run Code Online (Sandbox Code Playgroud)

在这里试试吧

  • 绝对应该是“接受”的答案(几乎错过了它,因为它不是)。谢谢。 (5认同)
  • @benshabatnoam,问题是询问如何在基类的构造函数中调用它,这个答案没有回答。 (2认同)

Dav*_*ret 16

执行顺序是:

  1. A的构造函数
  2. B的构造函数

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

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

所以发生以下情况:

var b = new B();     // undefined
b.MyvirtualMethod(); // "Test String"
Run Code Online (Sandbox Code Playgroud)

您需要更改代码才能处理此问题.例如,通过调用this.MyvirtualMethod()B的构造,通过创建一个工厂方法来创建对象,然后执行该功能,或通过将串入A的构造和工作了这一点莫名其妙......有很多的可能性.


Fla*_*ken 11

如果您希望超类从子类调用函数,最简单的方法是定义抽象模式,以这种方式您明确知道该方法存在于某处并且必须由子类重写.

这是一个例子,通常你不会在构造函数中调用sub方法,因为子实例还没有被初始化...(你在问题的例子中有一个"未定义"的原因)

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();
Run Code Online (Sandbox Code Playgroud)

在这里测试一下

如果像@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();
Run Code Online (Sandbox Code Playgroud)

在这里试试吧

  • 此解决方案将强制在每个子类中定义此方法,即使不需要它也是如此. (2认同)
  • @Max是摘要的唯一目的。我为你提供了一个例子 (2认同)