私は C++ の経験があり、特定の概念を Objective-C に変換する方法について少し混乱しています。
C++ では多重継承が許可されているため、次のような多くの設計が見られます。
class Z {
virtual void doSomething() {...}
};
class A : V, W, Z {
void doSomething() {...}
};
class B : X, Y, Z {
void doSomething() {...}
};
void callDoSomething(Z* inheritsFromZ) {
inheritsFromZ->doSomething();
}
A *a = new A();
callDoSomething(a);
これに関する重要なことは、ポインター inheritsFromZ のオブジェクトが持つ特定の型にとらわれずに済むということです。気にするのは、そのオブジェクトがクラス Z によって定義されたインターフェイスを実際に実装していることだけです。
Objective-C では多重継承は許可されていませんが、クラスで複数のプロトコルを使用することは許可されています。私にとっての問題は、C++ で Z* を使用できるように、変数またはセレクターのパラメーターを「プロトコル Z を使用するもの」として宣言する方法がわからないことです。
たとえば、Objective-C の簡単な擬似コードを次に示します。
@protocol A
- (void)selectorB;
@end
@interface C : NSObject <A>
@end
@implementation C
- (void)misc {
E* e = [[E alloc] initWithCallableA:self];
}
- (void)selectorB {
NSLog(@"In C");
}
@end
@interface D : NSObject <A>
@end
@implementation D
- (void)misc {
E* e = [[E alloc] initWithCallableA:self];
}
- (void)selectorB {
NSLog(@"In D");
}
@end
@interface E : NSObject
@end
@implementation E
- (id)initWithCallableA:(id)implementsA {
self = [super init];
if (self) {
[implementsA selectorB]; // compiler doesn't like this
}
return self;
}
@end
特定のクラスのオブジェクトへのより一般的なポインターしかない場合に、特定のクラスによって実装されたセレクターを呼び出す方法について、SO には多くの質問があります。たとえば、presentingViewController へのアクセス権があり、そのクラス タイプが M* であることはわかっていますが、Xcode はそれが単なる UIViewController* であると不平を言っています... これは、変数をキャストできる状況です。(きれいではありませんが、機能します。)
ここでの違いは、ポインターが複数のクラス型を参照できる場合であり、どのクラスが特定のプロトコルを実装しているかがわかるだけです。