Oltre ad essere fastidioso e facendo in modo che ogni singolo sottoclasse deve essere toccato quando una classe genitore è aggiornato ...Qual è lo scopo della chiamata super() nelle sottoclassi TS?
risposta
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.
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
Non sono sicuro di capire la differenza tra ciò che stai suggerendo e l'attuale modo 'super' di fare le cose. –
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