2016-07-07 13 views

risposta

5

Si consideri il seguente codice:

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

La chiamata a super nel ctor di classe B chiama la ctor della classe di A, e se guardiamo al compilato codice 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)); 

dovrebbe essere chiaro il motivo per cui lo facciamo, perché altrimenti tutto ciò accade nel ctor di A non accadrebbe, ovvero i membri x, e sum non verrebbero assegnati nelle istanze della classe B.

Si potrebbe quindi chiedere "bene, bene, ma perché non succede automaticamente? Perché il compilatore non può chiamare semplicemente super per me?"
Questa è una domanda giusta, e mi viene in mente 2 motivi principali:

(1) Perché a volte si vuole voler fare qualcosa prima di chiamare super, ad esempio:

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

è necessario chiamare super prima di accedere a this nel ctor di B.

(2) Rende esplicito che questo è ciò che sta accadendo, altrimenti potresti non aspettarti che accada perché non lo vedi.

Questo requisito è valido solo per i costruttori, i metodi di classe non sono richiesti per chiamare il proprio super, ma si è liberi di farlo se si desidera eseguire la funzionalità del metodo principale.

+0

Questo ha senso. Ma non esiste un metodo come _preconstruct() in cui vengono eseguite le funzioni pre-super di quelle sottoclassi? Sembra un modo migliore per andare che forzare ogni sottoclasse a replicare le condizioni del suo genitore. – user3583223

+0

Non sono sicuro di capire la differenza tra ciò che stai suggerendo e l'attuale modo 'super' di fare le cose. –

+0

Penso che @ user3583223 potrebbe suggerire che una funzione '_preconstruct()' potrebbe essere disponibile SOLO per le classi figlie che hanno bisogno di una logica nella chiamata a 'super()'. Tutte le classi figlie che non hanno bisogno di alcuna logica speciale potrebbero semplicemente avere una chiamata implicita a 'super()'. In altre parole, '_preconstruct()' sarebbe completamente opzionale, mentre le chiamate a 'super()' non sono opzionali. – MadScone

Problemi correlati