2016-07-07 13 views

Odpowiedz

5

Rozważmy następujący kod:

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

Wezwanie do super w ctor z Klasa B wywołuje konstruktor klasy A, a jeśli spojrzymy na skompilowanego kodu 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)); 

powinno być jasne, dlaczego robimy to, bo inaczej wszystko tak się zdarzy w ctor z A nie byłoby, czyli członkowie x, y i sum nie zostaną przypisani w przypadkach klasy B.

Możesz zapytać "no, dobrze, ale dlaczego to nie dzieje się automatycznie, dlaczego kompilator nie może po prostu zadzwonić pod numer super?"
To dobre pytanie, a ja mogę myśleć o 2 głównych powodów:

(1) Bo czasami chcesz chcą coś zrobić przed wywołaniem super, na przykład:

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

Musisz dzwonić super zanim uzyskasz dostęp do this w ctor of B.

(2) Podkreśla to wyraźnie, że tak się dzieje, w przeciwnym razie możesz nie oczekiwać, że tak się stanie, ponieważ go nie widzisz.

To wymaganie jest ważne tylko dla konstruktorów, metody klasy nie są wymagane, aby wywoływać ich super, ale możesz to zrobić, jeśli chcesz uruchomić funkcję metody nadrzędnej.

+0

To ma sens. Ale czy nie mogłaby istnieć metoda taka jak _preconstruct(), w której wykonywane są pre-super funkcje tej podklasy? Wydaje się, że jest to lepszy sposób niż zmuszanie każdej podklasy do replikowania warunków jej rodzica. – user3583223

+0

Nie jestem pewien, czy rozumiem różnicę między tym, co sugerujesz, a obecnym "super" sposobem robienia rzeczy. –

+0

Myślę, że @ user3583223 może sugerować, że funkcja '_preconstruct()' może być dostępna TYLKO dla klas potomnych, które potrzebują logiki w wywołaniu 'super()'. Wszystkie klasy potomne, które nie potrzebują żadnej specjalnej logiki, mogą mieć niejawne wywołanie 'super()'. Innymi słowy, '_preconstruct()' byłoby całkowicie opcjonalne, natomiast wywołania 'super()' nie są opcjonalne. – MadScone