0

私は 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* であると不平を言っています... これは、変数をキャストできる状況です。(きれいではありませんが、機能します。)

ここでの違いは、ポインターが複数のクラス型を参照できる場合であり、どのクラスが特定のプロトコルを実装しているかがわかるだけです。

4

2 に答える 2

3
    [implementsA selectorB]; // compiler doesn't like this

あなたの答えで考えるように、コンパイラはプロトコルに型付けをしていないため、これはそうではありません。チャックのコメントを参照してください。

おそらく、プロトコルをインポートするのを忘れただけです。

とにかく、プロトコルをタイプに追加する方が良い方法です。

于 2013-06-07T21:39:41.043 に答える
2

この質問を書いているときに、少なくともある程度は自分の質問に答えました。構文は次のようになります。

(id <A>)

一時的に使っていた場所の代わりに

(id)

ここを見る

于 2013-06-07T21:12:58.767 に答える