2011-12-15 11 views
5

मुझे ऑब्जेक्ट उन्मुख प्रोग्रामिंग का अनुभव है हालांकि यह स्थिति किसी कारण से अपरिचित है।अभिभावक वर्ग विधि से बच्चे वर्ग पर कॉलिंग विधि (उद्देश्य-सी 2.0)

@interface A : NSObject 
@end 

@implementation A 
- (void) f { 
    [self g]; 
} 
@end 

@interface B : A 
@end 

@implementation B 
- (void) g { 
    NSLog(@"called g..."); 
} 
@end 

यह सही तरीका है माता पिता कक्षा में एक विधि से एक बच्चे वर्ग पर एक विधि कॉल कर सकता: निम्नलिखित ऑब्जेक्टिव-सी 2.0 कोड पर विचार करें? क्या होता है यदि कोई अन्य बच्चा वर्ग g विधि लागू नहीं करता है? शायद मूल वर्ग A में एक अमूर्त विधि की तरह इसे हल करने का एक बेहतर तरीका है?

+1

[मूल से बच्चे को संदेश भेजा जा रहा] के संभावित डुप्लिकेट (http://stackoverflow.com/questions/3351937/sending-message-to आप इसे इस तरह इस्तेमाल किया देख सकते हैं -चिल्ड-से-पैरेंट) –

+1

यह भी देखें: [अपने सुपरक्लास से उप-वर्ग विधि को कॉल करें] (http://stackoverflow.com/questions/7515582/call-subclasss-method-from-its-superclass) –

उत्तर

11

कुंजी मूल कक्षा में एक विधि है जो कि बाल वर्ग में अतिरंजित हो सकती है।

@interface Dog : NSObject 
- (void) bark; 
@end 

@implementation Dog 
- (void) bark { 
    NSLog(@"Ruff!"); 
} 
@end 

@interface Chihuahua : Dog 
@end 

@implementation Chihuahua 
- (void) bark { 
    NSLog(@"Yipe! Yipe! Yipe!"); 
} 
@end 

आप देखते हैं कि आपका बच्चा वर्ग अपने कार्यान्वयन के साथ मूल विधि को ओवरराइड करेगा।

Dog *someDog = [Chihuahua alloc] init] autorelease]; 
[someDog bark]; 

आउटपुट:: Yipe! Yipe! Yipe!

+0

समझ में आता है। क्या माता-पिता वर्ग इंटरफ़ेस में 'छाल' घोषित करने की आवश्यकता है? आपके इंटरफ़ेस में – SundayMonday

+1

'छाल' घोषित किया जाना चाहिए। हाँ। – Jeremy

+1

एक अलग स्थिति हो सकती है जहां आप वास्तव में एक अलग विधि को कॉल करना चाहते हैं जैसे कि आपने जो वर्णन किया है। उदाहरण के लिए, आप टेम्पलेट पैटर्न का उपयोग करना चाह सकते हैं: [टेम्पलेट विधि पैटर्न] (http://en.wikipedia.org/wiki/Template_method_pattern), जैसे कि आप मेरे उदाहरण में 'छाल' को कॉल करना चाहते हैं, हालांकि, छाल इसके बदले में कुछ आंतरिक तरीकों को बुलाया जाएगा जिन्हें बाद में बाल वर्ग द्वारा ओवरराइड किया जाएगा, जैसे स्क्वीजी के उदाहरण की तरह। – Jeremy

3

आपको मूल कक्षा में g लागू करना चाहिए, लेकिन इसे कुछ भी नहीं करना चाहिए। इस तरह इसे बिना त्रुटि के कहा जा सकता है, लेकिन अभी भी ओवरराइड किया जा सकता है।

@interface A : NSObject 
@end 

@implementation A 
- (void) f { 
    [self g]; 
} 
- (void) g {} // Does nothing in baseclass 
@end 

@interface B : A 
@end 

@implementation B 
- (void) g { 
    NSLog(@"called g..."); 
} 
@end 

या आप इसे निष्पादित करने से पहले ऑब्जेक्ट पर विधि की जांच करते हैं।

if ([self respondsToSelector:@selector(g)]) { 
    [self performSelector:@selector(g) withObject:nil]; 
} 

लेकिन यह बहुत बदसूरत हो सकता है।

+0

कंपाइलर चेतावनियों को बंद कर देता है हालांकि, है ना? चूंकि संकलन सोचता है कि यह जानता है कि 'स्वयं' की कक्षा उस विधि को लागू नहीं करती है? –

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