2012-06-18 16 views
7

जब आप किसी बेस क्लास में क्लास कन्स्ट्रक्टर को परिभाषित करते हैं (यानी कुछ स्थिर वर्ग चर सेट करने के लिए), क्या यह क्लास कन्स्ट्रक्टर को व्युत्पन्न कक्षा में ओवरराइड करना संभव है और विरासत में के साथ कन्स्ट्रक्टर को अपने पदानुक्रमित माता-पिता से कॉल करना संभव है?क्या आप कक्षा के कन्स्ट्रक्टर को ओवरराइड कर सकते हैं और विरासत में उपयोग कर सकते हैं?

उदाहरण:

TBaseclass = class(TObject) 
public 
    class constructor ClassCreate; virtual; 
end; 

TOtherClass = class(TBaseClass) 
public 
    class constructor ClassCreate; override; 
end; 

**implementation** 

class constructor TBaseClass.ClassCreate; 
begin 
    //do some baseclass stuff 
end; 

class constructor TotherClass.ClassCreate; 
begin 
    inherited; 
    //do some other stuff 
end; 

उत्तर

16

वहाँ के लिए है क्योंकि वे polymorphically लागू नहीं किया जा सकता class constructors आभासी होने के लिए कोई कारण नहीं है। आप उन्हें सीधे कॉल नहीं कर सकते; कंपाइलर आवेषण स्वचालित रूप से उन्हें कॉल करता है कि किसी प्रोग्राम में कौन से वर्गों का उपयोग किया जाता है। वर्चुअल विधियां रन-टाइम पॉलीमोर्फिज्म के लिए हैं, लेकिन चूंकि संकलक जानता है कि कौन से वर्ग रचनाकार संकलन समय पर आविष्कार कर रहे हैं, कक्षा रचनाकारों या विनाशकों पर गतिशील प्रेषण की कोई आवश्यकता नहीं है।

विरासत के लिए वर्चुअल विधियों की आवश्यकता नहीं है, इसलिए, कक्षा निर्माणकर्ता या वर्ग विनाशक में inherited का उपयोग करने में कोई समस्या नहीं होनी चाहिए। David's answer बताते हैं, हालांकि, कंपाइलर inherited पर कॉल को अनदेखा करता है क्योंकि एक वर्ग को कई बार शुरू करने के लिए आम तौर पर मूर्खतापूर्ण होता है, जो आप वास्तव में विरासत वर्ग कन्स्ट्रक्टर को कॉल करने में कामयाब होते हैं। यदि ऐसा कुछ है जो आपको दो बार होने की आवश्यकता है, तो आपको इसे करने के लिए एक अलग तरीका खोजना होगा।

+1

+1 "कंपाइलर आवेषण स्वचालित रूप से उन्हें कॉल करता है कि किसी प्रोग्राम में कौन से वर्गों का उपयोग किया जाता है"। क्लास कन्स्ट्रक्टर मुख्य रूप से स्मार्टलिंकिंग को और अधिक कुशल बनाते हैं। (क्योंकि संबंधित वर्रों का प्रारंभ वर्ग के उपयोग पर सशर्त हो जाता है) –

+0

नहीं, @ मारजन। यह एक अयोग्य वोट नहीं था। यह किसी ऐसे व्यक्ति द्वारा मतदान था जिसने "कन्स्ट्रक्टर" के लिए "क्लास कन्स्ट्रक्टर" को गलत समझा और फिर मेरे और डेविड के दावों को अपवाद दिया कि वे आभासी नहीं हो सकते हैं और यदि वे कर सकते हैं तो इसका कोई फायदा नहीं होगा। पर्याप्त प्रतिष्ठा वाले लोग "विवादित" उत्तर देख सकते हैं जिसे बाद में हटा दिया गया था क्योंकि मैंने शब्दावली में गलतफहमी की ओर इशारा किया था। वोटों को समझाते हुए टिप्पणियां पहले ही हटा दी गई हैं। –

+0

काफी ईमानदार होने के लिए, उत्तर का वास्तविक विवरण मेरे सिर पर रास्ता है, क्योंकि सिर्फ मुझे ऐसा कुछ नहीं करना पड़ा है। लेकिन रॉब, +1, आप वास्तव में स्पष्टीकरण का एक मास्टर हैं। –

9

एक शुरुआत के लिए, के बाद से वर्ग कंस्ट्रक्टर्स आभासी नहीं किया जा सकता है (यह कोई मतलब नहीं है उन्हें आभासी होने के लिए), आप अपने कोड संकलन करने के लिए virtual और override कीवर्ड निकालने की जरूरत है।

क्लास कन्स्ट्रक्टर आमतौर पर कक्षा के युद्ध शुरू करने के लिए उपयोग किए जाते हैं। क्लास वर्र्स को आम तौर पर केवल एक बार और एक बार शुरू करने की आवश्यकता होती है। यदि आप प्रश्न में सुझाव देने के तरीके में inherited पर कॉल कर सकते हैं, तो TBaseClass.ClassCreate को कई बार बुलाया जाएगा जब वास्तव में इसे बिल्कुल एक बार कहा जाना चाहिए।

जबकि आप कक्षा निर्माणकर्ता में inherited लिख सकते हैं, और कोड संकलित होगा, संकलक बस इसे अनदेखा करता है।

program ClassConstructors; 

{$APPTYPE CONSOLE} 

uses 
    SysUtils; 

var 
    Count: Integer; 

type 
    TBaseclass = class 
    public 
    class constructor ClassCreate; 
    end; 

    TOtherClass = class(TBaseClass) 
    public 
    class constructor ClassCreate; 
    end; 

class constructor TBaseClass.ClassCreate; 
begin 
    inc(Count); 
end; 

class constructor TotherClass.ClassCreate; 
begin 
    inherited; 
end; 

begin 
    TBaseClass.Create.Free; 
    TOtherClass.Create.Free; 
    Writeln(Count);//outputs 1 
    Readln; 
end. 

ध्यान दें कि, निश्चित रूप से, दोनों वर्ग निर्माता भागते हैं।

+0

आपकी टिप्पणियों के लिए धन्यवाद! लेकिन क्या 'विरासत' कॉल हमेशा संकलक द्वारा अनदेखा हो जाते हैं? मैंने सोचा कि विरासत में निर्मित (AOwner) 'कुछ जगहें हैं। क्या डुप्लिकेट कॉल हैं? क्या आप टिप्पणी करने में मदद कर सकते हैं? – SOUser

+1

@XichenLi 'विरासत' केवल तभी अनदेखा हो जाता है जब इसका कोई अर्थ न हो। उदाहरण के लिए कक्षा रचनाकार। या विधियों में जो अमूर्त तरीकों को ओवरराइड करते हैं। –

+2

@ डेविडहेफरन: ओवरराइड अमूर्त तरीकों को विरासत में कॉल किया जाता है और यदि आप विरासत में 'विरासत में कुछ' वारसनाम करते हैं तो 'E/ESTSTRError उत्पन्न करते हैं;' –

संबंधित मुद्दे

 संबंधित मुद्दे