2009-06-13 16 views

उत्तर

80

जावा के रचनाकारों में से एक से पहले historical perspective on the topic, पहले बंद करें। इसके बाद, विकिपीडिया में मामूली मददगार section on Objective-C protocols है। विशेष रूप से, समझें कि उद्देश्य-सी दोनों औपचारिक प्रोटोकॉल (जिन्हें स्पष्ट रूप से @protocol कीवर्ड के साथ घोषित किया गया है, जावा इंटरफ़ेस के समतुल्य रूप से घोषित किया गया है) और अनौपचारिक प्रोटोकॉल (कक्षा द्वारा लागू एक या अधिक विधियां, जो हो सकती हैं प्रतिबिंब के माध्यम से खोजा गया)।

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

if ([myObject conformsToProtocol:@protocol(MyProtocol)]) { 
    ... 
} 

नोट: एप्पल के documentation कहता है:

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

ऑब्जेक्टिव-सी 2.0 के रूप में (में OS X 10.5 "तेंदुए" और iOS), औपचारिक प्रोटोकॉल अब परिभाषित कर सकते हैं वैकल्पिक तरीकों, और एक वर्ग के रूप में लंबे समय के रूप में यह सभी आवश्यक तरीकों को लागू करता है एक प्रोटोकॉल के अनुरूप है । @required (डिफ़ॉल्ट) और @optional कीवर्ड का उपयोग टॉगल करने के लिए कर सकते हैं कि का पालन करने वाली विधि घोषणाएं या प्रोटोकॉल के अनुरूप लागू हो सकती हैं। (ऐप्पल की Objective-C 2.0 Programming Language मार्गदर्शिका का अनुभाग देखें जो optional protocol methods पर चर्चा करता है।)

वैकल्पिक प्रोटोकॉल तरीकों डेवलपर्स के लिए बहुत लचीलापन को खोलने, विशेष रूप से प्रतिनिधियों और श्रोताओं लागू करने के लिए। MouseInputAdapter जैसे कुछ विस्तार करने के बजाय (जो परेशान हो सकता है, चूंकि जावा भी एकल विरासत है) या बहुत सी व्यर्थ, खाली विधियों को लागू करने के बजाय, आप प्रोटोकॉल को अपनाने और केवल उन्हीं वैकल्पिक तरीकों को लागू कर सकते हैं जिनकी आप परवाह करते हैं। इस पैटर्न के साथ, फोन करने वाले की जाँच करता है विधि यह लागू (-respondsToSelector का उपयोग कर) के पहले लागू किया गया है या नहीं:

if ([myObject respondsToSelector:@selector(fillArray:withObject:)]) { 
    [myObject fillArray:anArray withObject:foo]; 
    ... 
} 

प्रतिबिंब के भूमि के ऊपर एक समस्या बन जाता है, तो आप समय से पहले अनुकूलन करने के लिए इच्छा को दबाना हमेशा cache the boolean result for reuse सकते हैं, लेकिन । :-)

+4

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

+3

"यदि कोई ऑब्जेक्टिव-सी क्लास औपचारिक प्रोटोकॉल में निहित विधियों को लागू करता है, तो उसे उस प्रोटोकॉल को" अनुरूप "कहा जाता है, भले ही इसका इंटरफ़ेस स्पष्ट रूप से इसे अपनाने वाला न हो। आप कोड में प्रोटोकॉल अनुरूपता का परीक्षण कर सकते हैं (-conformsToProtocol का उपयोग करना :) इस तरह "यह गलत है। '-conformsToProtocol: 'क्लास स्पष्ट रूप से प्रोटोकॉल को गोद लेता है, तो केवल YES वापस कर देगा। क्या आपने यह भी कोशिश की है? – user102008

+2

आप सही हैं, '-कॉन्फोर्म्स टूप्रोटोकॉल:' वास्तव में यह आवश्यक है कि कक्षा (या पूर्वजों) औपचारिक रूप से घोषित करे कि यह प्रोटोकॉल को गोद ले। यकीन नहीं है कि मुझे यह गलत कैसे मिला, सुधार के लिए धन्यवाद! –

18

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

जैसे

उद्देश्य सी:

@protocol MyProtocol 
// Protocol definition 
@end 

id <MyProtocol> myProtocol; 

[myProtocol retain] // Compiler warning 

जावा:

public interface MyInterface { 
// interface definition 
} 

MyInterface myInterface; 

myInterface.toString(); // Works fine. 

उद्देश्य सी (निर्धारित):

@protocol MyProtocol <NSObject> 
// Protocol definition 
@end 

id <MyProtocol> myProtocol; 

[myProtocol retain] // No Warning 
+25

ऐसा इसलिए है क्योंकि आईडी और एनएसओब्जेक्ट * समान नहीं हैं *। जावा में, रूट ऑब्जेक्ट ऑब्जेक्ट है। उद्देश्य-सी में, NSObject एक मूल वस्तु है, लेकिन * * मूल वस्तु नहीं है। यदि आप सभी NSObject विधियों (कक्षा विधियों के साथ-साथ प्रोटोकॉल) तक पहुंच चाहते हैं, तो यह स्पष्ट रूप से बताएं: NSObject myProtocol; इसके बजाय: आईडी ... जब आप आईडी का उपयोग करते हैं तो आप कह रहे हैं: मुझे ऑब्जेक्ट की परवाह नहीं है, * केवल * प्रोटोकॉल, जो आपके मामले में सत्य नहीं है। –

+0

@JasonCoco cool: D – hqt

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