假设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
)。
然后,该-loadObject:
方法显示了 Objective-C 的动态性,以及您可以通过多种方式查询此时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 {
}
}