ClassA
、ClassB
、およびClassC
は次のように定義されているとしましょう。
@interface ClassA : NSObject {
}
- (void)methodA;
@end
@interface ClassB : ClassA {
}
- (void)methodB;
@end
@protocol ClassCProtocol <NSObject>
- (void)protocolMethodC;
@end
@interface ClassC : ClassA <ClassCProtocol> {
}
@end
興味深いことに、プロトコルから継承する@protocol
名前付きオブジェクトと、プロトコルのサブクラスでプロトコルに準拠するオブジェクトも定義しました(つまり、プロトコルに準拠するすべてのオブジェクトは、プロトコルを実装することが保証されています)。方法)。ClassCProtocol
<NSObject>
ClassC
ClassA
<ClassCProtocol>
-protocolMethodC
最初に注意すべきことは、Objective-C には、C++ にあるのと同じ意味での派生クラスのようなものは実際には存在しないということです。単一の継承しかないため、通常ClassB
、 のサブクラスClassA
、またはClassC
のサブクラスですClassA
。
が、状況に応じて、、またはMDLoadObject()
のインスタンスを返す関数であると仮定して、次のコードを使用します。ClassA
ClassB
ClassC
ClassA *MDLoadObject() {
ClassA *object = nil;
if (...) {
object = [[[ClassA alloc] init] autorelease];
} else if (...) {
object = [[[ClassB alloc] init] autorelease];
} else {
object = [[[ClassC alloc] init] autorelease];
}
return object;
}
@interface MDAppController : NSObject {
}
- (void)loadObject:(id)sender;
@end
@implementation MDAppController
- (void)loadObject:(id)sender {
ClassA *instanceOfClassABorC = MDLoadObject();
if ([instanceOfClassABorC isKindOfClass:[ClassB class]]) {
[(ClassB *)instanceOfClassABorC methodB];
} else if ([instanceOfClassABorC isKindOfClass:[ClassC class]]) {
[(ClassC *)instanceOfClassABorC protocolMethodC];
} else if ([instanceOfClassABorC respondsToSelector:@selector(protocolMethodC)) {
[(ClassC *)instanceOfClassABorC protocolMethodC];
} else {
}
}
@end
クラスClassB
との最上位の共通祖先ClassC
はであるため、 のインスタンスを返す関数ClassA
を定義します。(単一継承では、 と のすべてのインスタンスも のインスタンスであることが保証されていることに注意してください)。MDLoadObject()
ClassA
ClassB
ClassC
ClassA
このメソッドは、Objective-C のダイナミズムを示しており、この時点で関数-loadObject:
から返されたオブジェクトの型を調べる方法がいくつかあります。メソッドはキャストなしで書くこともでき、実行時に問題なく実行されることにMDLoadObject()
注意してください。-loadObject:
- (void)loadObject:(id)sender {
ClassA *instanceOfClassABorC = MDLoadObject();
if ([instanceOfClassABorC isKindOfClass:[ClassB class]]) {
[instanceOfClassABorC methodB];
} else if ([instanceOfClassABorC isKindOfClass:[ClassC class]]) {
[instanceOfClassABorC protocolMethodC];
} else if ([instanceOfClassABorC respondsToSelector:@selector(protocolMethodC)) {
[instanceOfClassABorC protocolMethodC];
} else {
}
}