2016-07-07 91 views

回答

5

考慮下面的代碼:

class A { 
    protected sum: number; 

    constructor(protected x: number, protected y: number) { 
     this.sum = this.x + this.y; 
    } 
} 

class B extends A { 
    constructor(x: number, y: number) { 
     super(x, y); 
    } 
} 

中的構造函數來super調用類B調用A類的構造函數,如果我們看一下編譯JavaScript代碼:

var __extends = (this && this.__extends) || function (d, b) { 
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 
    function __() { this.constructor = d; } 
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 
}; 
var A = (function() { 
    function A(x, y) { 
     this.x = x; 
     this.y = y; 
     this.sum = this.x + this.y; 
    } 
    return A; 
}()); 
var B = (function (_super) { 
    __extends(B, _super); 
    function B(x, y) { 
     _super.call(this, x, y); 
    } 
    return B; 
}(A)); 

應該清楚,爲什麼我們這樣做,否則一切發生在A的ctor中的情況不會發生,即在類B的實例中將不會分配成員x,ysum

然後你可能會問「好吧,好,但爲什麼不會自動發生?爲什麼編譯器不能爲我調用super?」
這是一個公平的問題,我能想到的兩個主要的原因:

(1)因爲有時候你很想很想打電話super之前做一些事情,例如:

class A { 
    protected sum: number; 

    constructor(protected x: number, protected y: number) { 
     this.sum = this.x + this.y; 
    } 
} 

class B extends A { 
    constructor(x: number, y: number) { 
     if (x % 2 === 0) { 
      super(x, y); 
     } else { 
      super(x + 1, y); 
     } 
    } 
} 

你必須調用superB的訪問中訪問this之前。 (2)它明確表示這是發生了什麼,否則你可能不會期望它發生,因爲你看不到它。

這個要求只對構造函數有效,類方法不需要調用它們的super,但是如果你想執行父方法的功能,你可以自由地這樣做。

+0

這很有道理。但是不能像_preconstruct()這樣的方法存在於那些子類的pre-super函數被執行的地方嗎?似乎比強迫每個子類複製其父項的條件更好。 – user3583223

+0

我不確定我是否理解你所提出的建議與目前的「超級」做事方式之間的差異。 –

+0

我認爲@ user3583223可能暗示一個'_preconstruct()'函數可用於只需要調用'super()'時需要一些邏輯的子類。所有不需要任何特殊邏輯的子類都可以隱式調用'super()'。換句話說,'_preconstruct()'是完全可選的,而對'super()'的調用不是可選的。 – MadScone

相關問題