2011-12-15 24 views
5

オブジェクト指向プログラミングに関する経験はありますが、何らかの理由でこの状況がよくわかりません。親クラスメソッドからの子クラスの呼び出しメソッド(Objective-c 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 

これは、親クラスのメソッドから子クラスのメソッドを呼び出す正しい方法ですか?別の子クラスがメソッドgを実装していない場合はどうなりますか?おそらく親クラスの抽象メソッドのようにこれを解決するより良い方法がありますA

+1

可能重複(http://stackoverflow.com/questions/3351937/sending-message-to -child-from-parent) –

+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

意味があります。親クラスインターフェイスで 'bark'を宣言する必要がありますか? – SundayMonday

+1

'bark'はあなたのインターフェースで宣言されるべきです。はい。 – Jeremy

+1

説明したような別のメソッドを実際に呼び出したい場合は、別の状況があります。たとえば、テンプレートパターン[テンプレートメソッドパターン](http://en.wikipedia.org/wiki/Template_method_pattern)を使用したい場合は、私の例のように 'bark'を呼びたい場合と同様ですが、樹皮Squegyの例のように、子クラスによってオーバーライドされるいくつかの内部メソッドを呼び出します。 – 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

コンパイラが警告を発生させますしかし、それはありませんか?コンパイルは 'self'のクラスがそのメソッドを実装していないことを知っていると思っているので? –

関連する問題