2015-09-08 10 views
7

ECMAScript 6 (Harmony) wprowadza classes z możliwością dziedziczenia jednego z drugiego. Załóżmy, że mam grę i podstawową klasę opisującą podstawowe rzeczy na zachowanie bota. Upraszczam moją prawdziwą architekturę, ale przypuśćmy, że potrzebuję uruchomić render i inną rutynę, a te wywołania podałem w podstawowej klasie Bot.Funkcja nadrzędnego wywołania konstruktora zastąpiła funkcje przed ukończeniem wszystkich konstruktorów podrzędnych.

Każdy bot wtedy przesłonić to render funkcji i może mieć pewne ustawienia w konstruktorze:

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

Problem polega na tym, że zanim zadzwonię super() - this nie istnieje. Ale super (konstruktor nadrzędny) wywoła zastąpienie render, które wymagałoby zmiennej color zdefiniowanej w konstruktorze podrzędnym. Mogę przypuszczać w konstruktorze dominującej że obiekt dziecko będzie realizować pewne init funkcji ze wszystkich potrzebnych ustawień i nazwać go:

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

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

Ale jak dobry to podejście i co jest preferowanym sposobem rozwiązania tego problemu?

+2

Jedynym rozwiązaniem jest nie nazywaj przeciążać metody w konstruktorze. zrobienie tego w C# da ci [ostrzeżenie] (https://msdn.microsoft.com/en-us/library/ms182331.aspx). –

+0

Jest to jeden z powodów, dla których obiekty niektórych typów często mają konstruktor i oddzielną metodę '.init()', ponieważ metoda '.init()' działa po całkowitym uformowaniu obiektu i przy wszystkich ustawieniach. – jfriend00

+0

Rozwiązanie może być tak proste, jak automatyczne wywoływanie innych funkcji (takich jak "render"), które zależą od właściwości instancji. Co jest złego w wywołaniu 'this.render()' ręcznie po wywołaniu podklas "Bot"? PS, aby wywołać funkcję członka w twojej klasie, będziesz potrzebował 'this.render()' zamiast 'render()'. – naomik

Odpowiedz

5

Poniższy kod będzie robić to, co chcesz, ale to jest obecnie obsługiwane tylko w FF i Chrome 47+ 41+ (patrz 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 
Powiązane problemy