2010-07-11 13 views
12

मैं ऑब्जेक्टिव-सी श्रेणियों के संबंध में नियमों की एक जोड़ी के बारे में पता:क्या होता है यदि दो ओबीजेसी श्रेणियां एक ही विधि को ओवरराइड करती हैं?

  1. श्रेणी तरीकों मौजूदा तरीकों (वर्ग या उदाहरण)
  2. दो अलग श्रेणियों उसी के लिए एक ही विधि को लागू करने पर हावी नहीं होना चाहिए वर्ग अपरिभाषित व्यवहार में परिणाम होगा

मुझे पता है क्या होता है जब मैं टी में अपने ही वर्ग तरीकों में से एक को ओवरराइड चाहते हैं वह वही श्रेणी है। उदाहरण के लिए:

@interface NSView (MyExtensions) 
- (void)foo; // NSView category implementation 
@end 

@interface MyClass : NSView 
{ } 
@end 

@interface MyClass (MyExtensions) 
- (void)foo; // MyClass category implementation 
@end 

इन इंटरफेस परिभाषित किए जाने के साथ, जब मैं निम्नलिखित कोड चलाता हूं तो कौन सी विधि निष्पादित की जाएगी?

MyClass * instance = [[MyClass alloc] initWith...]; 
[instance foo]; 
[instance release]; 

नोट: मेरी संकलक के साथ, MyClass कार्यान्वयन पूर्वता लेता है, लेकिन मुझे यकीन है कि अगर वह या होने की गारंटी है, बस एक अपरिभाषित व्यवहार के विशिष्ट स्वाद नहीं हूँ।

उत्तर

12

प्रत्येक वर्ग की प्रत्येक विधि एक कार्यान्वयन है। एक श्रेणी एक विशिष्ट वर्ग के लिए एक विधि जोड़ या बदलती है। इसका मतलब है कि आप जो व्यवहार देख रहे हैं, जहां MyClass में foo है और NSView में foo है, अच्छी तरह परिभाषित है। MyClass के किसी भी मामले में एक अलग foo NSView के किसी भी मामले है कि एक MyClass नहीं है, बस के रूप में अगर foo मुख्य कार्यान्वयन में नहीं परिभाषित किया गया था और एक वर्ग से होगा। NSView के लिए परिभाषित foo तक पहुंचने के लिए आपको MyClass से [super foo] पर भी कॉल करने में सक्षम होना चाहिए।

+3

क्या सुपर क्लास श्रेणी में घोषित और लागू श्रेणी विधि में ओवरराइड करना सही है? – BergP

32

खींचा उत्तर पर विस्तार करने के लिए:

यह पदानुक्रम का मामला है। श्रेणियां वास्तव में स्रोत फ़ाइलों को व्यवस्थित करने का साधन हैं। संकलित करते समय, किसी भी श्रेणी में परिभाषित समेत कक्षा के सभी तरीकों, एक ही फ़ाइल में समाप्त होते हैं।

आप किसी भी श्रेणी में नियमित कक्षा इंटरफ़ेस में जो कुछ भी कर सकते हैं, आप किसी भी श्रेणी में कर सकते हैं और नियमित श्रेणी इंटरफ़ेस में नहीं करना चाहिए, आपको किसी श्रेणी में नहीं करना चाहिए।

तो:

श्रेणी तरीकों मौजूदा तरीकों (वर्ग या उदाहरण) पर हावी नहीं चाहिए

आप ओवरराइड करने के लिए नियमित रूप से वर्ग इंटरफ़ेस में निर्धारित तरीकों का उपयोग कर सकते हैं तरीकों विरासत में मिला है तो आप कर सकते हैं एक श्रेणी में विरासत विधियों को ओवरराइड करें।

हालांकि, आप एक वर्ग या तो साधारण इंटरफ़ेस या पर अन्य वर्ग में एक विधि के रूप में एक ही नाम है जो में एक विधि कभी नहीं होना चाहिए एक ही साधारण इंटरफ़ेस में दो समान विधि परिभाषाओं करने के लिए कोशिश कभी नहीं होगा एक ही कक्षा। चूंकि सभी विधि परिभाषाएं एक ही संकलित फ़ाइल में समाप्त होती हैं, इसलिए वे स्पष्ट रूप से टकराएंगे।

दो अलग-अलग श्रेणियों को लागू करने अपरिभाषित व्यवहार में एक ही विधि का परिणाम

फिर से लिखा जाना चाहिए कि कहने के लिए "दो अलग-अलग श्रेणियों में एक ही वर्ग के लिए एक ही विधि को लागू करने परिणाम अपरिभाषित में व्यवहार।" दोबारा, क्योंकि किसी एक वर्ग के लिए सभी विधियां एक ही फाइल में समाप्त होती हैं, उसी वर्ग में दो विधियां होने से जाहिर तौर पर अजीबता होती है।

आप सुपरक्लास विधियों को ओवरराइड करने वाली विधियों को प्रदान करने के लिए श्रेणियों का उपयोग कर सकते हैं क्योंकि एक वर्ग और इसके सुपरक्लास दो अलग-अलग वर्ग हैं।

यदि आप कभी भी इस बारे में उलझन में हैं कि कोई श्रेणी समस्या का कारण बनती है तो बस खुद से यह पूछें: "क्या श्रेणी में विधियां काम करती हैं अगर मैंने उन्हें सभी वर्गों में कॉपी और चिपकाया '.h/.m फाइलें?" अगर उत्तर "हां" है तो आप स्पष्ट हैं। यदि "नहीं", तो आपको समस्याएं हैं।

+2

+1 धन्यवाद। यह वर्णन करने का एक बहुत अच्छा तरीका है। मैंने आपके मिलान के लिए नियम # 2 पर शब्द भी बदल दिया है। –

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