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

时间:2015-06-13 14:19:45

标签: 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
    }
}

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

4 个答案:

答案 0 :(得分:62)

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

答案 1 :(得分:16)

执行顺序是:

  1. A的构造函数
  2. B的构造函数
  3. B的构造函数 - A - 被调用之后,_super的构造函数中的赋值发生了:

    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()的构造函数中调用B,通过创建工厂方法来创建对象然后执行函数,或者将字符串传递给A的构造函数,以某种方式解决这个问题......有很多可能性。

答案 2 :(得分:8)

如果你想让一个超类从一个子类调用一个函数,最简单的方法就是定义一个抽象模式,这样你明确地知道该方法存在于某个地方并且必须被子类覆盖。

这是一个例子,通常你不会在构造函数中调用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();

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

试试Here

答案 3 :(得分:0)

下面是一个通用示例

RunWith
相关问题