2010-03-06 10 views
20

क्या उद्देश्य सी इंटरफ़ेस में एक से अधिक कार्यान्वयन हो सकते हैं? उदाहरण में मेरे पास एक इंटरफेस हो सकता है लेकिन 2 कार्यान्वयन एक जहां मैं एक सरणी या दूसरे का उपयोग करता हूं जहां मैं इसे लागू करने के लिए एक स्टैक..एटीसी का उपयोग करता हूं।क्या एक उद्देश्य सी इंटरफ़ेस में एक से अधिक कार्यान्वयन हो सकते हैं?

यदि ऐसा है तो आप इसे/वाक्यविन्यास कैसे कहते हैं?

+0

"प्रोटोकॉल" का उपयोग करने के बारे में कैसे? यह जावा/सी # इंटरफेस के करीब है। मैं क्या चाहता हूं? – user48545

उत्तर

25

ऑब्जेक्टिव-सी एक प्रोटोकॉल है, जो एक अंतरफलक के विनिर्देश है की अवधारणा है। प्रोटोकॉल के माध्यम से, उद्देश्य-सी पूरी तरह से विनिर्देश के एकाधिक विरासत का समर्थन करता है (लेकिन कार्यान्वयन नहीं)। तो, थोड़ा उलझन में, @interface वाक्यविन्यास वास्तव में कक्षा (कार्यान्वयन) को परिभाषित करता है, जो केवल एकल विरासत का समर्थन करता है, लेकिन प्रोटोकॉल, या इंटरफेस के विनिर्देशों के कई/एकाधिक विरासत के कार्यान्वयन को निर्दिष्ट कर सकता है। अंत में, यह जावा में प्रकृति में बहुत समान है।

उदाहरण के लिए:

@protocol SomeInterface 
- (void)interfaceMethod1; 
- (void)interfaceMethod2; 
@end 

@interface SomeClass:NSObject <SomeInterface> 
@end 

@interface AnotherClass:NSObject <SomeInterface> 
@end 

या तो SomeClass या AnotherClass दोनों के उदाहरण दावा है कि वे कार्यान्वयन SomeInterfaceप्रोटोकॉल के लिए आवश्यक प्रदान करते हैं।

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

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

id <SomeInterface> obj; 
:

SomeClass * someObject = [[SomeClass alloc] init; 
[someObject someUnspecifiedMethod]; // Compiles with warning - no op 
[someObject interfaceMethod1]; 

आप कुछ है कि किसी भी वर्ग (@interface) हो सकता है टाइप परिभाषित करना चाहते हैं, लेकिन एक विशिष्ट इंटरफ़ेस लागू करता है (@protocol), तो आप कुछ इस तरह उपयोग कर सकते हैं

obj या तो SomeClass या AnotherClass ऑब्जेक्ट रख सकता है।

+0

आप सही हैं ... मैंने एक और अधिक "आधार" प्रश्न का जवाब दिया (और वास्तव में ओपी नहीं पूछ रहा था) ... फिर से पढ़ने के बाद, मैं देख सकता हूं कि ओपी शायद कुछ और के साथ लाइन में दिख रहा था आपका उत्तर/अमूर्त कारखानों/वर्ग क्लस्टर। – rcw3

3

आप इस तरह के उदाहरण के लिए मतलब है:

@interface MasterViewController : 
    UIViewController <GKPeerPickerControllerDelegate, 
        GKSessionDelegate, 
        UITextFieldDelegate, 
        UITableViewDelegate, 
        AVAudioRecorderDelegate> { 
} 
+0

या क्या आप वास्तव में अधिक मतलब है कि एक @ कार्यान्वयन/@ अंत ब्लॉक? –

+0

यह अलग-अलग वर्गों और कार्यान्वयन के निर्माण के साथ कई प्रतिनिधियों को घोषित करने के तरीके की तलाश में पाया गया। यह पूरी तरह से काम किया। 2 साल बाद धन्यवाद। –

24

शायद आपको Class Cluster नामक कोको पैटर्न को आजमाएं। इसका उपयोग शुरू करने के लिए आपको SomeClass और दो निजी उप-वर्ग SomeArrayClass और SomeStackClass नामक सार्वजनिक कक्षा बनाने की आवश्यकता है। जब आपको स्टैक का उपयोग करने की आवश्यकता होती है तो आपका पब्लिक क्लास कन्स्ट्रक्टर SomeStackClass का उदाहरण देगा और इसे SomeClass के सार्वजनिक रूप से उपलब्ध उदाहरण के रूप में वापस कर देगा।

+1

यह वही पैटर्न है जिसका आप उपयोग करना चाहते हैं। – bbum

+0

"प्रोटोकॉल" का उपयोग करने के बारे में कैसे? यह जावा/सी # इंटरफेस के करीब है। जो मैं चाहता हूं वह है। – user48545

20

(यदि आप इसे वोट देते हैं, तो कृपया रोमन को वोट दें - उसका जवाब पहले था, सही है, बस एक उदाहरण की कमी है)।

आप Class Cluster के बारे में बात कर रहे हैं। उदाहरण के लिए, एनएसएसटींग कक्षा देखें।

@interface NSString : NSObject 

और NSMutableString:

@interface NSMutableString : NSString 

जिनमें से

दोनों एक कोर वर्ग की घोषणा में तरीकों में से अत्यंत छोटे सेट की घोषणा

NSString नहीं है। यदि आप अपनी खुद की स्ट्रिंग क्लास को लागू करने के लिए एनएसएसटींग को उप-वर्ग करना चाहते थे, तो आपको केवल उन कोर विधियों को लागू करने की आवश्यकता होगीएनएसएसटींग में लागू सभी अन्य विधियों को उन कोर विधियों के संदर्भ में लागू किया गया है। और, इसी प्रकार, उत्परिवर्तन विधियों को एनएसएमयूटेबलस्ट्रिंग के मूल में घोषित आदिम विधियों का उपयोग करके कार्यान्वित किया जाता है।

अब, जाहिर है, - (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)aString (एक कोर विधि) के माध्यम से सभी उत्परिवर्तन को लागू करना काफी अक्षम होगा। इस प्रकार, रनटाइम पर, आप ध्यान देंगे कि आपके पास वास्तव में एनएसएसटींग या एनएसएमयूटेबलस्ट्रिंग का उदाहरण नहीं है, लेकिन केवल उप-वर्गों के उदाहरण (जो वास्तव में, वास्तव में उपclasses नहीं हैं ... लेकिन वे संदर्भ में भी हो सकते हैं इस चर्चा के)।

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

@interface MyAbstractClass : NSObject 
... declare factory methods here ... 
... declare core methods here ... 
@end 

@interface MyAbstractClass(AdditionalFunctionality) 
... declare convenience here ... 
@end 

फिर, कार्यान्वयन में, कोर के तरीकों के संदर्भ में @throw @"Must use subclass" के रूप में कोर तरीकों और सभी AdditionalFunctionality तरीकों के सभी लागू:

तो, आप की तरह कुछ करना होगा।

यह पूरी तरह से निजी हो सकता है - नहीं एक शीर्षक में सब पर, यहां तक ​​कि:

@interface MyStackClass: MyAbstractClass @end

@implementation MyStackClass ... कोर तरीकों को लागू करने और ओवरराइड addalfunctionality विधियों जो अनुकूलन की जरूरत है ... @end

अपने अतिरिक्त प्रकार के वर्गों के लिए दोहराएं। फिर, MyAbstractClass पर फ़ैक्टरी विधियों को लागू करें जो आवश्यकतानुसार सबक्लास के उदाहरण लौटाते हैं।

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

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