多态的特性在iOS开发,尤其是在整个app的架构搭建当中,用的比较多,一般在比较大,复杂的app中应用广泛。理解多态,能够写出比较优雅的代码,设计出优秀的应用架构。
抽象的打印机类Printer
Printer.h
#import
@interface Printer : NSObject
- (void) print;
@end
|
就是一个简单的方法print
Printer.m
#import "Printer.h"
@implementation Printer
- (void)print{
NSLog(@
"打印机打印纸张"
);
}
@end
|
实现也是很简单的
下面来看一下具体的子类
ColorPrinter.h
#import "Printer.h"
//修改父类的打印行为
@interface ColorPrinter : Printer
- (void)print;
@end
|
ColorPrinter.m
#import "ColorPrinter.h"
@implementation ColorPrinter
- (void)print{
NSLog(@
"彩色打印机"
);
}
@end
|
在看一下另外一个子类
BlackPrinter.h
BlackPrinter.m
|
#import "BlackPrinter.h"
@implementation BlackPrinter
- (void)print{
NSLog(@
"黑白打印机"
);
}
@end
|
这里我们在定义一个Person类,用来操作具体的打印机
Person.h
|
Person.m
#import "Person.h"
@implementation Person
/*
- (void) printWithColor:(ColorPrinter *)colorPrint{
[colorPrint print];
}
- (void) printWithBlack:(BlackPrinter *)blackPrint{
[blackPrint print];
}
*/
- (void) doPrint:(Printer *)printer{
[printer print];
}
@end
|
再来看一下测试代码:
main.m
// main.m
#import
#import "Person.h"
#import "BlackPrinter.h"
#import "ColorPrinter.h"
int main(int argc, const charchar * argv[]) {
@autoreleasepool {
Person *person =[[Person alloc] init];
ColorPrinter *colorPrint = [[ColorPrinter alloc] init];
BlackPrinter *blackPrint = [[BlackPrinter alloc] init];
//多态的定义
/*
Printer *p1 = [[ColorPrinter alloc] init];
Printer *p2 = [[BlackPrinter alloc] init];
[person doPrint:p1];
[person doPrint:p2];
*/
//通过控制台输入的命令来控制使用哪个打印机
int cmd;
do
{
scanf(
"%d"
,&cmd);
if
(cmd == 1){
[person doPrint:colorPrint];
}
else
if
(cmd == 2){
[person doPrint:blackPrint];
}
}
while
(1);
}
return
0;
}
|
下面就来详细讲解一下多态的好处
上面的例子是一个彩色打印机和黑白打印机这两种打印机,然后Person类中有一个操作打印的方法,当然这个方法是需要打印机对象的,如果不用多态机制实现的话(Person.h中注释的代码部分),就是给两种打印机单独定义个操作的方法,然后在Person.m(代码中注释的部分)中用具体的打印机对象进行操作,在main.m文件中,我们看到,当Person需要使用哪个打印机的时候,就去调用指定的方法:
1
2
|
[person printWithBlack:blackPrint];
//调用黑白打印机
[person printWithColor:colorPrint];
//调用彩色打印机
|
这种设计就不好了,为什么呢?假如现在又有一种打印机,那么我们还需要在Person.h中定义一种操作这种打印机的方法,那么后续如果在添加新的打印机呢?还在添加方法吗?那么Person.h文件就会变得很臃肿。所以这时候多态就体现到好处了,使用父类类型,在Person.h中定义一个方法就可以了:
1
|
- (void) doPrint:(Printer *)printer;
|
这里看到了,这个方法的参数类型就是父类的类型,这就是多态,定义类型为父类类型,实际类型为子类类型
1
2
3
|
- (void) doPrint:(Printer *)printer{
[printer print];
}
|
这里调用print方法,就是传递进来的实际类型的print方法。
1
2
3
4
5
|
Printer *p1 = [[ColorPrinter alloc] init];
Printer *p2 = [[BlackPrinter alloc] init];
[person doPrint:p1];
[person doPrint:p2];
|
这里的p1,p2表面上的类型是Printer,但是实际类型是子类类型,所以会调用他们自己对应的print方法。点击下载demo