उद्देश्य-सी कई विरासत


88

मेरे पास 2 कक्षाएं हैं जिनमें एक मेथड शामिल है और दूसरा मेथडब शामिल है। इसलिए एक नई कक्षा में मुझे मेथड मेथड और मैथड बी से आगे निकलने की जरूरत है। तो मैं उद्देश्य सी में कई विरासत कैसे प्राप्त करूं? मैं वाक्य रचना के साथ थोड़ा भ्रमित हूँ।

जवाबों:


136

उद्देश्य-सी कई उत्तराधिकार का समर्थन नहीं करता है, और आपको इसकी आवश्यकता नहीं है। संरचना का उपयोग करें:

@interface ClassA : NSObject {
}

-(void)methodA;

@end

@interface ClassB : NSObject {
}

-(void)methodB;

@end

@interface MyClass : NSObject {
  ClassA *a;
  ClassB *b;
}

-(id)initWithA:(ClassA *)anA b:(ClassB *)aB;

-(void)methodA;
-(void)methodB;

@end

अब आपको बस संबंधित आइवर पर विधि लागू करने की आवश्यकता है। यह अधिक कोड है, लेकिन वस्तुनिष्ठ-सी में भाषा की विशेषता के रूप में सिर्फ एक ही वंशानुक्रम नहीं है।


8
वंशानुक्रम से लेने के लिए रचना अक्सर एक बेहतर दृष्टिकोण है, खासकर यदि आप कोड पर बहुत इकाई परीक्षण करते हैं। यह बहुत अधिक लचीलापन देता है कि आप आसानी से कक्षा को फिर से परिभाषित किए बिना कार्यान्वयन को स्वैप कर सकते हैं। जब आप चाहें तब विशेष रूप से काम करें, मॉक ऑब्जेक्ट के लिए क्लासए और क्लासबी को स्वैप करें। यहां तक ​​कि रनटाइम स्वैपिंग इम्प्लीमेंटेशन (जैसे FTPFileStore vs LocalFileStore) रचना के साथ क्लीनर बन जाता है। इसका मतलब यह नहीं है कि विरासत में यह जगह नहीं है, लेकिन कई वंशानुक्रम की आवश्यकता है कि मैं अपने डिज़ाइन पर फिर से विचार करूं;)
d11wtq

1
मुझे यह समझ में नहीं आता है। क्या आपको तुरंत ClassAऔर जरूरत नहीं है ClassB? बुला करता है methodA:पर MyClassकिसी भी तरह स्वचालित रूप से फोन methodA:पर ClassA?
zakdances

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


1
d11wtq, शानदार जवाब! इसके अतिरिक्त, संदेश अग्रेषण आपको री-इम्प्लीमेंटिंग मेथड और मेथडब के चरण को छोड़ देता है। थोड़े से काम के साथ संदेश स्वचालित रूप से उपयुक्त वस्तुओं के लिए भेजा जा सकता है। डेवलपर
.apple.com

3

यह है कि मैं एक एकल "माता-पिता" के रूप में सिंग्लटनपैट कोड को कोड करता हूं मूल रूप से मैंने प्रोटोकॉल और श्रेणी के संयोजन का उपयोग किया था।

केवल एक चीज जो मैं नहीं जोड़ सकता वह एक नया "आइवर" है, हालांकि, मैं इसे संबंधित ऑब्जेक्ट के साथ धक्का दे सकता हूं।

#import <Foundation/Foundation.h>
@protocol BGSuperSingleton
+(id) singleton1;
+(instancetype)singleton;
@end

@interface NSObject (singleton) <BGSuperSingleton>

@end

static NSMutableDictionary * allTheSingletons;

+(instancetype)singleton
{
    return [self singleton1];
}
+(id) singleton1
{
    NSString* className = NSStringFromClass([self class]);

    if (!allTheSingletons)
    {
        allTheSingletons = NSMutableDictionary.dictionary;
    }

    id result = allTheSingletons[className];

    //PO(result);
    if (result==nil)
    {
        result = [[[self class] alloc]init];
        allTheSingletons[className]=result;
        [result additionalInitialization];
    }
    return result;
}

-(void) additionalInitialization
{

}

जब भी मैं इस BGSuperSingleton मैं "विरासत" के लिए एक वर्ग चाहता हूं

#import "NSObject+singleton.h"

और जोड़ @interface MyNewClass () <BGSuperSingleton>


2
श्रेणियाँ एकाधिक उत्तराधिकार नहीं हैं। वे पहले से मौजूद वर्ग के तरीकों / कार्यों से निपटने का एक तरीका हैं। एकाधिक वंशानुक्रम एक तिहाई वर्ग को एक या अधिक वर्गों (चर सहित) के संयोजन की अनुमति देता है। मुझे श्रेणियां पसंद हैं। श्रेणियाँ बहुत उपयोगी हैं। लेकिन वे कई विरासत नहीं हैं।
लॉयड सार्जेंट

लेकिन UIViewController का एक उपवर्ग "समर्थन" भी कर सकता है, इस मामले में, सिंगलटन पैटर्न मुझे चाहिए।
सेप्टियादी अगुस

तकनीकी रूप से सभी NSManagedObject "को अब" [obj सिंगलटन] कह सकते हैं। मैं उन लोगों को सेट करता हूं जिन्हें मैं प्रोटोकॉल के समर्थन से चाहता हूं। वैसे भी कई विरासत के रूप में अच्छा है। यह तभी है जब मैं बच्चे के वर्ग को अभिभावक के इंटरफेस और कार्यान्वयन दोनों का समर्थन करना चाहता हूं। यदि केवल कार्यान्वयन तो स्पष्ट रूप से रचना का रास्ता है।
सेप्टियादी अगुस

बस <BGSuperSingleton> जैसे प्रोटोकॉल को जोड़ने से कक्षाएं नहीं बनती हैं, फिर "सिंगलटन" विधि को कॉल करने में सक्षम हो। आपको अभी भी इसे लागू करना है ...
कॉममाटॉस्ट

-4

क्या आप प्रोटोकॉल के बारे में जानते हैं, प्रोटोकॉल कई वंशानुक्रम को लागू करने का तरीका है


12
+1 "उन वर्गों के बीच समानताएं पकड़ने के लिए जो पदानुक्रम से संबंधित नहीं हैं।" डेवलपर
.apple.com

7
इस मामले में, जहां दोनों तरीकों को ओवरराइड किया जाएगा, प्रोटोकॉल ट्रिक करेंगे। अन्य मामलों में जब आप कोड का पुन: उपयोग करने के लिए वंशानुक्रम का उपयोग करना चाहते हैं, तो प्रोटोकॉल मदद नहीं करेंगे। हालाँकि, यह आमतौर पर कक्षाओं को एक दूसरे से विरासत में मिला कर या उन्हें जोड़कर हल किया जा सकता है, आमतौर पर इसे सही तरीके से प्राप्त करने का एक तरीका है यदि उपवर्ग वास्तव में 2 वर्गों के साथ कोड साझा करता है।
jake_hetfield 11

आप प्रोटोकॉल को किसी श्रेणी या रचना के साथ जोड़ सकते हैं।
सेप्टियाडी अगुस

-1 क्योंकि प्रोटोकॉल कई वंशानुक्रम के लिए बिल्कुल भी नहीं हैं। इसी तरह JAVA, Interfacesकई विरासत प्रदान करने या नकल करने के लिए नहीं हैं।
थिसुमर्सगिन

1
Apple के स्वयं के प्रलेखन से @FreeAsInBeer एक प्रोटोकॉल प्रोग्रामेटिक इंटरफ़ेस की घोषणा करता है जिसे कोई भी वर्ग कार्यान्वित करना चुन सकता है। प्रोटोकॉल एक निश्चित लक्ष्य को पूरा करने के लिए एक दूसरे के साथ संवाद करने के लिए वंशानुक्रम से संबंधित दो वर्गों के लिए संभव बनाता है। वे इस प्रकार उपवर्ग का एक विकल्प प्रदान करते हैं । जैसा कि आप देख सकते हैं कि Apple स्पष्ट रूप से उपवर्ग का उपयोग कर रहा है अर्थात अनुगामी। शायद निकेश ने अपने उत्तर में इसे शामिल किया, अपने तर्क को स्पष्ट करने में मददगार होगा
हनी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.