Call an overridden method from super class in type

2020-02-26 02:54发布

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.

3条回答
爷、活的狠高调
2楼-- · 2020-02-26 03:00

The key is calling the parent's method using 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

查看更多
可以哭但决不认输i
3楼-- · 2020-02-26 03:01

The order of execution is:

  1. A's constructor
  2. B's constructor

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

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.

查看更多
劫难
4楼-- · 2020-02-26 03:24

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.

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

查看更多
登录 后发表回答