2015-09-08 11 views
7

ECMAScript 6 (Harmony) introduce classes con la possibilità di ereditarne uno da un altro. Supponiamo che io abbia un gioco e alcune lezioni di base per descrivere le cose di base per il comportamento dei bot. Semplifico la mia vera architettura, ma suppongo di dover eseguire render e qualche altra routine e inserisco queste chiamate nella classe base Bot.Le chiamate sovrascritte del costruttore genitore funzionano prima che tutti i costruttori figli siano finiti

Ogni bot poi ignorare è render funzione e può avere alcune impostazioni nel costruttore:

class DevilBot extends Bot{ 
    constructor(){ 
    super(); 
    this.color = 0xB4D333; 
    } 
    render(){ 
    createSomeMesh(this.color); 
    } 
} 

Il problema qui è che prima che chiami super() - this non esiste. Ma il numero super (costruttore principale) chiamerà l'override render che richiederebbe la variabile color definita nel costruttore figlio. Posso Suppongo che nel costruttore genitore che l'oggetto bambino sarebbe implementare una qualche funzione init con tutte le impostazioni necessarie e chiamare:

class Bot{ 
    constructor(){ 
    if (this.init) this.init(); 
    render(); 
    } 
    render(){} 
} 

class DevilBot extends Bot{ 
    init(){ 
    this.color = 0xB4D333; 
    } 
    render(){ 
    createSomeMesh(this.color); 
    } 
} 

Ma quanto è buono questo approccio e quello che è un modo preferito per risolvere un tale problema?

+2

L'unica soluzione è non chiamare overridable metodo nel costruttore. farlo in C# ti darà un [avvertimento] (https://msdn.microsoft.com/en-us/library/ms182331.aspx). –

+0

Questo è uno dei motivi per cui gli oggetti di alcuni tipi hanno spesso un costruttore e un metodo '.init()' separato perché il metodo '.init()' viene eseguito dopo che l'oggetto è stato completamente formato e tutti gli override sono stati posizionati. – jfriend00

+0

La soluzione potrebbe essere semplice come non chiamare automaticamente altre funzioni (come 'render') che dipendono dalle proprietà dell'istanza. Qual è il danno nel chiamare 'this.render()' manualmente dopo aver richiamato le sottoclassi 'Bot'? PS, per chiamare una funzione membro all'interno della tua classe, avrai bisogno di 'this.render()' invece di 'render()'. – naomik

risposta

5

Il seguente codice fare quello che vuoi, anche se è attualmente supportata solo in FF e Chrome 41+ 47+ (vedi https://kangax.github.io/compat-table/es6/)

class Bot{ 
    constructor(){ 
     if (new.target === Bot) 
      this.render(); 
    } 
    render(){ 
     console.log('Bot rendered'); 
    } 
} 

class DevilBot extends Bot{ 
    constructor(){ 
     super(); 
     this.color = 0xB4D333; 
     this.render(); 
    } 
    render(){ 
     console.log('DevilBot rendered with', this.color); 
    } 
} 

var bot = new Bot();  // Bot rendered 
var dev = new DevilBot(); // DevilBot rendered with 11850547 
Problemi correlati