2015-06-13 13 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

निर्माता में आभासी विधि कॉलिंग किसी भी OOP भाषा में एक बुरा व्यवहार माना जाता है: https://google.com/search?q=virtual+method+in+constructor –

उत्तर

11

निष्पादन के आदेश है:

  1. A के निर्माता
  2. B के निर्माता रों constructor- _super -Has 'A के बाद रों निर्माता'

काम B में होता है कहा जाता है:

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" 

आप इस से निपटने के लिए अपने कोड को बदलने के लिए की आवश्यकता होगी। उदाहरण के लिए, B के कन्स्ट्रक्टर में ऑब्जेक्ट बनाने के लिए फ़ैक्टरी विधि बनाकर और फिर फ़ंक्शन निष्पादित करके या स्ट्रिंग को A के कन्स्ट्रक्टर में पास करके और किसी भी तरह से काम करके ... बहुत सारी संभावनाएं हैं।

+0

OO हाँ .. समझ गया। धन्यवाद। मैंने सोचा कि संपत्ति कन्स्ट्रक्टर से पहले शुरू होती है। – Sency

+0

क्या हम यहां ऐसे मामले में नहीं हैं जहां 'new.target' उपयोगी हो सकता है? – GameAlchemist

24

कुंजी 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

आप एक सुपर वर्ग एक उपवर्ग से एक समारोह कॉल करने के लिए चाहते हैं, स्पष्ट तरीका इस तरह से आप स्पष्ट रूप से पता विधि कहीं मौजूद है और अधिरोहित किया जाना चाहिए एक सार पैटर्न को परिभाषित करने के लिए है, एक उपclass द्वारा।

यह एक उदाहरण के रूप में है, आम तौर पर आप निर्माता के भीतर एक उप विधि कॉल नहीं है के रूप में उप उदाहरण अभी तक प्रारंभ नहीं किया गया है ... (कारण है कि आप एक "अनिर्धारित" अपने प्रश्न के उदाहरण में है)

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

@ मैक्स यह सार का एकमात्र उद्देश्य है। मैंने आपके जवाब में एक उदाहरण दिया है –