假设以下类别已定义:
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
为了增加趣味性,我还定义了一个名为
ClassCProtocol
的
@protocol
,它继承自
<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 {
}
}
MONClassB
的超类(即没有定义超类)是什么? - NSGod