2015-06-13 4 views
16

Когда я вызываю переопределенный метод из конструктора суперкласса, я не могу правильно получить значение свойства подкласса.Вызвать переопределенный метод из суперкласса в машинописном тексте

пример

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

Я хотел бы знать, как правильно переопределить функции в машинописи.

+5

Вызов виртуального метода в конструкторе считается плохой практикой в ​​любом языке ООП: https://google.com/search?q=virtual+method+in+constructor –

ответ

11

Порядок исполнения является:

  1. A 's конструктор
  2. B' s конструктор

Назначение происходит в B 's конструктора после A' s constructor- _super -обладает были вызваны:

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

Так происходит следующее:

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

Вам нужно будет изменить свой код, чтобы справиться с этим. Например, позвонив this.MyvirtualMethod() в конструктор B, создав фабричный метод для создания объекта, а затем выполнив эту функцию, или передав строку в конструктор A и получив какой-то способ ... есть много возможностей.

+0

OO да .. понял. Благодарю. Я думал, что свойство инициализируется перед конструктором. – Sency

+0

Разве мы здесь, в случае, когда 'new.target' может быть полезным? – GameAlchemist

24

Ключ вызывает метод parent, используя 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

Если вы хотите супер класса для вызова функции из подкласса, чистейший способ определить абстрактный рисунок, таким образом, вы явно знаете метод существует где-то и должны быть отменены подкласс.

Это в качестве примера, как правило, вы не вызываете метод суб в конструкторе, как вспомогательный экземпляр не инициализируется еще ... (причина, почему у вас есть «не определено» в примере на ваш вопрос в)

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

Протестируйте его Here

И если вам нравится @Max, вы действительно хотите избежать реализации абстрактного метода во всем мире, просто избавитесь от него. Я не рекомендую этот подход, потому что вы можете забыть, что вы переопределяете метод.

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

Попробуйте Here

+0

Это решение заставит вас определить этот метод в каждом дочернем классе, даже если он не нужен. – Max

+0

@Max это единственная цель абстрактного. Я привел пример в свой ответ за вас –