1、基本介绍
多态对于面向对象思想来说,个人感觉是真的很重要,他对以后的编写代码的优雅方式也是起到很重要的作用,其实现在很多设计模式中大部分都是用到了多态的特性,Java中的多态特性用起来很是方便的,但是C++中就很难用了,其实多态说白了就是:定义类型和实际类型,一般是基于接口的形式实现的,不多说了,直接看例子吧:
打印机的例子
抽象的打印机类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
#import "BlackPrinter.h" @implementation BlackPrinter - (void)print{ NSLog(@"黑白打印机"); } @end
这里我们在定义一个Person类,用来操作具体的打印机
Person.h
1 #import "Person.h" 2 3 @implementation Person 4 5 /* 6 - (void) printWithColor:(ColorPrinter *)colorPrint{ 7 [colorPrint print]; 8 } 9 10 - (void) printWithBlack:(BlackPrinter *)blackPrint{ 11 [blackPrint print]; 12 } 13 */ 14 15 - (void) doPrint:(Printer *)printer{ 16 [printer print]; 17 } 18 19 @end
再来看一下测试代码:
main.m
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #import 2 3 #import "Person.h" 4 #import "BlackPrinter.h" 5 #import "ColorPrinter.h" 6 7 int main(int argc, const charchar * argv[]) { 8 @autoreleasepool { 9 10 Person *person =[[Person alloc] init]; 11 12 ColorPrinter *colorPrint = [[ColorPrinter alloc] init]; 13 BlackPrinter *blackPrint = [[BlackPrinter alloc] init]; 14 15 //多态的定义 16 /* 17 Printer *p1 = [[ColorPrinter alloc] init]; 18 Printer *p2 = [[BlackPrinter alloc] init]; 19 20 [person doPrint:p1]; 21 [person doPrint:p2]; 22 */ 23 24 //通过控制台输入的命令来控制使用哪个打印机 25 int cmd; 26 do{ 27 scanf("%d",&cmd); 28 if(cmd == 1){ 29 [person doPrint:colorPrint]; 30 }else if(cmd == 2){ 31 [person doPrint:blackPrint]; 32 } 33 }while (1); 34 35 } 36 return 0; 37 }
下面就来详细讲解一下多态的好处
上面的例子是一个彩色打印机和黑白打印机这两种打印机,然后Person类中有一个操作打印的方法,当然这个方法是需要打印机对象的,如果不用多态机制实现的话(Person.h中注释的代码部分),就是给两种打印机单独定义个操作的方法,然后在Person.m(代码中注释的部分)中用具体的打印机对象进行操作,在main.m文件中,我们看到,当Person需要使用哪个打印机的时候,就去调用指定的方法:
[person printWithBlack:blackPrint];//调用黑白打印机 [person printWithColor:colorPrint];//调用彩色打印机
这种设计就不好了,为什么呢?假如现在又有一种打印机,那么我们还需要在Person.h中定义一种操作这种打印机的方法,那么后续如果在添加新的打印机呢?还在添加方法吗?那么 Person.h文件就会变得很臃肿。所以这时候多态就体现到好处了,使用父类类型,在Person.h中定义一个方法就可以了:
- (void) doPrint:(Printer *)printer;
这里看到了,这个方法的参数类型就是父类的类型,这就是多态,定义类型为父类类型,实际类型为子类类型
- (void) doPrint:(Printer *)printer{ [printer print]; }
这里调用print方法,就是传递进来的实际类型的print方法。
Printer *p1 = [[ColorPrinter alloc] init]; Printer *p2 = [[BlackPrinter alloc] init]; [person doPrint:p1]; [person doPrint:p2];
这里的p1,p2表面上的类型是Printer,但是实际类型是子类类型,所以会调用他们自己对应的print方法。
从上面的例子中我们就可以看到多态的特新很是重要,当然也是三大特性中比较难理解的。
2、多态的其它知识点
1.多态的体现
Person *p = [Student new];
p->age = 100;
[p walk];
子类对象赋值给父类指针
父类指针访问对应的属性和方法
2.多态的好处
用父类接收参数,节省代码
3.多态的局限性
不能访问子类的属性(可以考虑强制转换)
4.多态的细节
动态绑定:在运行时根据对象的类型确定动态调用的方法