2015-06-13 8 views
16

Podczas wywoływania nadpisanej metody z konstruktora klasy super, nie mogę poprawnie uzyskać wartości właściwości podklasy.Wywołanie nadpisanej metody z superklasy w pismach maszynowych

przykład

class A 
{ 
    constructor() 
    { 
     this.MyvirtualMethod(); 
    } 

    protected MyvirtualMethod(): void 
    { 

    } 
} 

class B extends A 
{ 
    private testString: string = "Test String"; 

    public MyvirtualMethod(): void 
    { 
     alert(this.testString); // This becomes undefined 
    } 
} 

Chciałbym wiedzieć, jak prawidłowo zastępują funkcje w maszynopisie.

+5

Wywołanie metody wirtualnych w konstruktorze jest uważane za złą praktyką w dowolnym języku OOP: https://google.com/search?q=virtual+method+in+constructor –

Odpowiedz

11

Kolejność wykonania jest:

  1. A jest konstruktor
  2. B jest konstruktor

Przyporządkowanie występuje B 'konstruktora a po A jest constructor- _super -has nazwano:

function B() { 
    _super.apply(this, arguments); // MyvirtualMethod called in here 
    this.testString = "Test String"; // testString assigned here 
} 

Więc dodaje się dzieje:

var b = new B();  // undefined 
b.MyvirtualMethod(); // "Test String" 

Trzeba będzie zmienić kod, aby sobie z tym poradzić. Na przykład wywołując this.MyvirtualMethod() w konstruktorze B, tworząc metodę fabryką, aby utworzyć obiekt, a następnie wykonując funkcję, lub przekazując ciąg do konstruktora A i pracując jakoś ... istnieje wiele możliwości.

+0

OO yea .. Rozumiem. Dzięki. Myślałem, że właściwość zainicjować przed konstruktorem. – Sency

+0

Czy nie jesteśmy tutaj w przypadku, gdy 'new.target' może być użyteczny? – GameAlchemist

24

Klucz wywołuje metodę rodzica za pomocą metody super.methodName();

class A { 
    // A protected method 
    protected doStuff() 
    { 
     alert("Called from A"); 
    } 

    // Expose the protected method as a public function 
    public callDoStuff() 
    { 
     this.doStuff(); 
    } 
} 

class B extends A { 

    // Override the protected method 
    protected doStuff() 
    { 
     // If we want we can still explicitly call the initial method 
     super.doStuff(); 
     alert("Called from B"); 
    } 
} 

var a = new A(); 
a.callDoStuff(); // Will only alert "Called from A" 

var b = new B() 
b.callDoStuff(); // Will alert "Called from A" then "Called from B" 

Try it here

5

Jeśli chcesz super klasa wywołać funkcję z podklasy, najczystszym sposobem jest zdefiniowanie abstrakcyjny wzór, w ten sposób jawnie wiedzieć metoda istnieje gdzieś i muszą być zastępowane przez podklasę.

to jako przykład, zazwyczaj nie wywołać metodę sub wewnątrz konstruktora jako sub instancji nie jest jeszcze zainicjowany ... (powód, dla którego mają „nieokreślone” na przykład dane pytanie)

abstract class A { 
    // The abstract method the subclass will have to call 
    protected abstract doStuff():void; 

    constructor(){ 
    alert("Super class A constructed, calling now 'doStuff'") 
    this.doStuff(); 
    } 
} 

class B extends A{ 

    // Define here the abstract method 
    protected doStuff() 
    { 
     alert("Submethod called"); 
    } 
} 

var b = new B(); 

Przetestuj Here

A jeśli lubisz @Max, naprawdę chcesz uniknąć wprowadzania abstrakcyjnej metody wszędzie, po prostu się ją pozbyć. Nie polecam tego podejścia, ponieważ możesz zapomnieć, że nadpisujesz metodę.

abstract class A { 
    constructor() { 
     alert("Super class A constructed, calling now 'doStuff'") 
     this.doStuff(); 
    } 

    // The fallback method the subclass will call if not overridden 
    protected doStuff(): void { 
     alert("Default doStuff"); 
    }; 
} 

class B extends A { 
    // Override doStuff() 
    protected doStuff() { 
     alert("Submethod called"); 
    } 
} 

class C extends A { 
    // No doStuff() overriding, fallback on A.doStuff() 
} 

var b = new B(); 
var c = new C(); 

Wypróbuj Here

+0

To rozwiązanie wymusi zdefiniowanie tej metody w każdej klasie potomnej, nawet jeśli nie jest potrzebna. – Max

+0

@Max to jedyny cel abstrakcji. Podaję przykład w mojej odpowiedzi dla ciebie –

Powiązane problemy