簡體   English   中英

在打字稿的基類構造函數中調用重寫的方法

[英]Call an overridden method in base class constructor in 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
    }
}

我想知道如何正確覆蓋打字稿中的函數。

關鍵是使用 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"

在這里試試

執行順序為:

  1. A的構造函數
  2. B的構造函數

A的構造函數_super被調用之后,賦值發生在B的構造函數中:

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"

您將需要更改代碼來處理此問題。 例如,通過在B的構造函數中調用this.MyvirtualMethod() ,通過創建一個工廠方法來創建對象然后執行函數,或者通過將字符串傳遞給A的構造函數並以某種方式解決......很多可能性。

如果您希望超類從子類調用函數,最簡潔的方法是定義抽象模式,通過這種方式,您明確知道該方法存在於某處並且必須被子類覆蓋。

這是一個例子,通常您不會在構造函數中調用子方法,因為子實例尚未初始化......(原因是您的問題示例中有“未定義”)

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

在這里測試

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

在這里試試

下面是一個通用示例

    //base class
    class A {
        
        // The virtual method
        protected virtualStuff1?():void;
    
        public Stuff2(){
            //Calling overridden child method by parent if implemented
            this.virtualStuff1 && this.virtualStuff1();
            alert("Baseclass Stuff2");
        }
    }
    
    //class B implementing virtual method
    class B extends A{
        
        // overriding virtual method
        public virtualStuff1()
        {
            alert("Class B virtualStuff1");
        }
    }
    
    //Class C not implementing virtual method
    class C extends A{
     
    }
    
    var b1 = new B();
    var c1= new C();
    b1.Stuff2();
    b1.virtualStuff1();
    c1.Stuff2();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM