多态
多态指的是允许父类的指针指向子类的对象,当指针指向不同的子类对象时,给它发送同一个消息就会有不同的响应.
如下定义一个父类Animal和二个子类Dog,Cat.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| @interface Animal : NSObject
- (void)run;
+ (void)bark;
+ (void)canClimb:(void(^)(BOOL can))blk;
@end
@implementation Animal
- (void)run { NSLog(@"%@ run", self); }
+ (void)bark { NSLog(@"%@ bark", self); }
+ (void)canClimb:(void (^)(BOOL))blk { !blk ?: blk(NO); }
@end
... @implementation Dog
- (void)run { NSLog(@"%@ run", self); }
+ (void)bark { NSLog(@"%@ bark", self); }
+ (void)canClimb:(void (^)(BOOL))blk { !blk ?: blk(NO); }
@end
...
@implementation Cat
- (void)run { NSLog(@"%@ run", self); }
+ (void)bark { NSLog(@"%@ bark", self); }
+ (void)canClimb:(void (^)(BOOL))blk { !blk ?: blk(YES); }
@end
|
接下来我们来个反射+多态:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| NSArray *clsArr = @[@"Animal", @"Dog", @"Cat"]; for (NSString *clsStr in clsArr) { Class cls = NSClassFromString(clsStr); id obj = [cls new]; [obj run]; }
for (NSString *clsStr in clsArr) { Class cls = NSClassFromString(clsStr); [cls performSelector:@selector(bark)]; }
for (NSString *clsStr in clsArr) { Class cls = NSClassFromString(clsStr); [cls canClimb:^(BOOL can){ NSLog(@"%@ can climb:%d",cls, can); }]; }
for (NSString *clsStr in clsArr) { Class cls = NSClassFromString(clsStr); [cls performSelector:@selector(canClimb:) withObject:^(BOOL can){ NSLog(@"%@ can climb:%d",cls, can); }]; }
|
以上需要注意的是:
Xcode对于id类型调用实例方法,实例方法会有补全提示.对于Class类型调用类方法,类方法就没有补全提示,但你写全后也不会报错.
对于类方法的动态调用可以使用performSelector
,也可以手动写全,这里Xcode不会自动补全不知道为什么.