3

ここにテンプレートメソッド patternがあり、Java と C++ は仮想関数を使用して簡単に実装できます。このパターンを実装するオブジェクト C はどうですか? ココアタッチ(iOS)の例はありますか?

4

3 に答える 3

4

jerがすでに指摘しているように、すべてのObjective-Cメソッドは本質的に仮想ですこれは、他のCのような言語と完全には一致しない言語の機能です。そうは言っても、テンプレートメソッドパターンの基本は、サブクラスに特定の関数を実装するように「手動で」強制することで、Objective-Cでも実現できます。例(リンクされたウィキペディアの記事の規則を使用):

@interface Game
{
    int playersCount;
}
- (void)playOneGame:(int)numPlayers;
// "virtual" methods: 
- (void)initializeGame;
- (void)makePlay:(int)player;
- (BOOL)endOfGame;
- (void)printWinner;
@end

@implementation Game
- (void)initializeGame         { NSAssert(FALSE); }
- (void)makePlay:(int player)  { NSAssert(FALSE); }
- (BOOL)endOfGame              { NSAssert(FALSE); return 0; }
- (void)printWinner            { NSAssert(FALSE); }
- (void)playOneGame:(int)numPlayers
{
    //..
}
@end

上記のコードGameは、基本クラスの実装の1つが呼び出された瞬間に例外をスローすることにより、のサブクラスに「仮想」メソッドをオーバーライドするように強制します。事実上、これにより、テストがコンパイラー段階(C ++またはJavaの場合のように)からランタイム段階(Objective-Cで同様のことが行われることが多い)に移動します。

サブクラスがメソッドをオーバーライドすることを許可されないというルールを本当に適用したい場合は、メソッドplayOneGame:内から正しい実装を検証するために(*)を試みることができます。init

@implementation Game
...
- (void)init
{
    if ((self = [super init]) == nil) { return nil; }

    IMP my_imp = [Game instanceMethodForSelector:@selector(playOneGame:)];
    IMP imp = [[self class] instanceMethodForSelector:@selector(playOneGame:)];
    NSAssert(imp == my_imp);

    return self;
}
...
@end

(*)Objective-Cの性質上、正しい結果を生成するためにplayOneGame:サブクラスをオーバーライドできるため、このコードは、再実装するサブクラスに対する100%の堅固な防御にはならないことに注意してください。instanceMethodForSelector:

于 2010-12-29T04:14:09.123 に答える
0

Objective-C では、すべてのメソッドが C++virtualメソッドに似ています。

于 2010-12-29T03:02:23.183 に答える