假设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>ClassCClassA<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 {
}
}