2011-09-19 10 views
17

मैं उद्देश्य-सी प्रोटोकॉल और श्रेणियों के आस-पास कुछ अवधारणाओं के बारे में थोड़ा उलझन में हूं।उद्देश्य-सी प्रोटोकॉल और श्रेणियां विरासत में मिल सकती हैं?

प्रोटोकॉल और श्रेणियों ऑब्जेक्टिव-सी में उपवर्गों द्वारा विरासत में मिला जा सकता है?

उत्तर

31

श्रेणियाँ रन टाइम पर एक वर्ग के लिए जोड़ रहे हैं कि तरीकों का संग्रह कर रहे हैं। चूंकि उद्देश्य-सी गतिशील बाध्यकारी का उपयोग करता है, इसका मतलब है कि किसी श्रेणी में परिभाषित विधियां कक्षा और उसके सभी उप-वर्गों के लिए उपलब्ध हैं। विशिष्ट रूप से चयनकर्ता उस बिंदु पर विधियों से बंधे होते हैं जहां उन्हें बुलाया जाता है, संकलन के दौरान नहीं या जब प्रोग्राम पहले लोड होता है। श्रेणियों को श्रेणियों में जोड़ा जाता है जब वे (श्रेणियां) लोड होते हैं।

प्रोटोकॉल विधि हस्ताक्षर के संग्रह को परिभाषित करते हैं जो कक्षाएं उनके अनुरूप होने का वादा करती हैं। एक बार कक्षा ने घोषणा की है कि यह प्रोटोकॉल के अनुरूप है जैसे कि उस वर्ग के इंटरफ़ेस में विधियों को घोषित किया गया है और विरासत के नियम बिल्कुल समान हैं: उप-वर्ग प्रोटोकॉल विधियों की घोषणा और कार्यान्वयन का उत्तराधिकारी है लेकिन सुपरक्लास को ओवरराइड करना भी चुन सकता है कार्यान्वयन।

प्रोटोकॉल खुद को नए प्रोटोकॉल का उत्पादन करने के लिए बढ़ाया जा सकता है। मूल प्रोटोकॉल में विधियों के एक सुपरसेट शामिल है। वास्तव में, जैसे अधिकांश वर्ग NSObject वर्ग से प्राप्त होते हैं, अधिकांश प्रोटोकॉल NSObject प्रोटोकॉल (प्रोटोकॉल नाम और कक्षा के नाम अलग-अलग नाम रिक्त स्थान में होते हैं) का विस्तार करते हैं। ऐसा इसलिए है कि id<WhateverProtocol> के रूप में घोषित वस्तुओं को -retain, -release जैसे मूल संदेशों को भेजा जा सकता है और इसलिए कंपाइलर चेतावनियां उत्पन्न किए बिना।

+1

'ओब्जे-सी' रनटाइम –

+1

का उल्लेख करने के लिए +1 लोकप्रिय उदाहरण होगा: @protocol UITableViewDelegate । –

6

श्रेणियाँ कक्षा के विस्तार की तरह हैं। आप अन्य वर्गों (जैसे एनएसएसटींग या कुछ और) में अपनी विधियां जोड़ सकते हैं। जिसका अर्थ है कि किसी भी सबक्लास को विधियों को भी प्राप्त होता है।

जबकि प्रोटोकॉल विधियों की एक सूची है जिसके लिए कक्षा की आवश्यकता होती है जो इसे सभी को लागू करने के लिए पुष्टि करता है (जब तक कि यह @optional टैग का उपयोग न करे)। तो इसके उत्तराधिकारी के लिए इसके उप-वर्ग का कोई बिंदु नहीं है।

संपादित करें:

प्रोटोकॉल कार्यान्वयन के लिए, मुझे एहसास हुआ कि मैं काफी स्पष्ट नहीं था। प्रोटोकॉल विधियों को जो इसके सुपरक्लास में लागू किया गया था विरासत में हो सकता है, हालांकि, मेरा मतलब था कि आमतौर पर आपको अपने सुपरक्लास की प्रोटोकॉल विधि को ओवरराइड करने की आवश्यकता नहीं होती है।

+3

अधिक विशेष रूप से के अनुरूप है: एक subclass अपने माता पिता के प्रोटोकॉल अनुरूपता विरासत में मिलता है। तो यदि कोई वर्ग के अनुरूप है, तो इसके उप-वर्ग भी के अनुरूप हैं। –

+0

हाँ, यही वह है जो मैं कह रहा था। धन्यवाद। – TheAmateurProgrammer

4

आपका प्रश्न अस्पष्ट है। आप पूछ सकते हैं कि सबक्लास को प्रोटोकॉल और उनके सुपरक्लास की श्रेणियों का उत्तराधिकारी है या नहीं। @theAmateurProgrammer ने इसका उत्तर दिया है।

आप यह भी पूछ सकते हैं कि श्रेणियां और प्रोटोकॉल स्वयं अन्य श्रेणियों और प्रोटोकॉल से प्राप्त हो सकते हैं या नहीं। श्रेणियों के लिए, जवाब नहीं है। प्रोटोकॉल के लिए, जवाब है हां, और वास्तव में प्रोटोकॉल लगभग हमेशा सिर्फ इस तरह वर्गों की तरह वारिस चाहिए:

@protocol SomeProtocol <NSObject> 
... 
@end 

यह कहना है कि कुछ भी है कि <SomeProtocol> के अनुरूप भी <NSObject> के अनुरूप है (जो एक प्रोटोकॉल के रूप में अच्छी तरह से एक के रूप में कक्षा)। यह आपको respondsToSelector: जैसी विधियों को कॉल करने की अनुमति देता है, जो अधिकांश प्रोटोकॉल कार्यान्वयन के लिए बहुत महत्वपूर्ण है।

+0

इस उत्तर का आधा मूल प्रश्न पर एक टिप्पणी है। दूसरी ओर, उसने आज के लिए मेरे प्रश्न का उत्तर दिया, तो +1। धन्यवाद। –

2

प्रोटोकॉल जावा में इंटरफेस की तरह हैं। तो, एक वर्ग इसे एक्सेस करने के लिए एक प्रोटोकॉल प्रदान करता है।

आप "उपवर्ग" प्रोटोकॉल सिर्फ जावा में है जैसे आप "उपवर्ग" कर सकते हैं कर सकते हैं इंटरफेस।

दूसरी ओर श्रेणियां कक्षा में और विधियों को जोड़ने का एक तरीका है। प्रतिबंध यह है कि आप किसी श्रेणी के साथ कोई इंस्टेंस चर नहीं जोड़ सकते हैं। आप केवल मौजूदा आवृत्ति चर का उपयोग कर सकते हैं।

हालांकि यह बहुत उपयोगी है क्योंकि यह एक बड़े नाजुक सबक्लास पदानुक्रम बनाने से बचाता है।

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

हालांकि, ध्यान में रखना एक बात यह है कि जब आप किसी श्रेणी में विधियों को जोड़ते हैं - कुछ मुझे कार्यकर्ताओं द्वारा याद दिलाया जाता है - यह है कि आप उन तरीकों को हर जगह उपलब्ध करा रहे हैं। मैंने कुछ स्थानों में पढ़ा है कि एक सामान्य नौसिखिया गलती श्रेणियों के साथ पागल होनी है, नौकरी करने वाले नए वर्ग बनाने के बजाय उन्हें हर समय इस्तेमाल करना।

तो, यदि आप जिस नई श्रेणी विधि पर विचार कर रहे हैं वह वास्तव में विशिष्ट है या बल्कि - कसकर युग्मित है - एक व्यापार समारोह के लिए, तो शायद यह एक श्रेणी नहीं होनी चाहिए। वे वास्तव में केवल बेस क्लास के सामान्य जोड़ों के लिए उपयोग किया जाना चाहिए।

1

NSObject NSObject प्रोटोकॉल के अनुरूप

@interface NSObject <NSObject> { 
    Class isa OBJC_ISA_AVAILABILITY; 
} 

कहते हैं कि हम NSObject का एक उपवर्ग है

@interface FTGAnimal : NSObject 

@end 

@implementation FTGAnimal 

@end 

हम देख सकते हैं कि FTGAnimal वास्तव में NSObject प्रोटोकॉल

if ([FTGAnimal conformsToProtocol:@protocol(NSObject)]) { 
     NSLog(@"FTGAnimal conforms to NSObject protocol"); 
} 
संबंधित मुद्दे