多态
多态的概念
有这样一个例子.早上我和同事说口渴了.结果:A同事拿着我的水杯去给我接了一杯水.B同事顺手在饮水机上拿了一次性纸杯给我接了杯水。C同事给了我一瓶他早上刚买的饮料。同事们得到的是同样的请求,但是三个人都有各自的解决办法,这就是多态。
在面向对象的程序设计理论中,多态(polymer phism)指的是,同一操作作用于不同类的实例时,将产生不同的执行效果.即不同类的对象收到相同的消息时,也能得到不同的结果.
我们知道,OC是一门动态语言,在使用多态时,系统会进行动态检测,以调用真实的对象方法. 在具有继承关系的前提下,多态在代码中体现为父类指针指向子类对象.
实现:
首先创建一个Animal类,让其继承自NSObject
Animal.h
@interface Animal : NSObject // 声明动物吃东西的方法 - (void)eat; @end
Animal.m
@implementation Animal - (void)eat { NSLog(@"动物吃东西"); } @end
再创建一个一个Cat类和Dog类,分别重写自己独有的方法.
Cat 类
Cat.h // Cat继承自Animal类
@interface Cat : Animal @end
Cat.m
@implementation Cat // 重写猫独有的方法- (void)eat { NSLog(@"猫吃鱼"); } @end
Dog类
Dog.h // Dog继承自Animal类,拥有了Animal所有的属性和方法@interface Dog : Animal @end
Dog.m
@implementation Dog
// 重写狗独有的方法- (void)eat { NSLog(@"狗吃骨头"); } @end
回到main中实现:
// 创建animal对象 Animal *animal = [[Animal alloc] init]; // 多态的实现: //1. 父类指针指向子类对象 animal = [[Cat alloc] init]; // 此时调用的方法到底是 动物吃东西呢? 还是猫吃东西呢? [animal eat]; //2. animal = [[Dog alloc] init]; [animal eat];
打印:
2015-11-27 17:31:38.975 DuoTai[1597:251835] 猫吃鱼
2015-11-27 17:31:38.975 DuoTai[1597:251835] 狗吃骨头
下面,我们再来看这样两行代码:
Dog *dog = [[Animal alloc] init]; // 动物是一条狗?这样的逻辑正确吗??
NSString *string = [[Dog alloc] init]; // 狗是一个字符串??
由上面发现:
OC语言是一门弱语法的语言,编译的时候并不会报错,系统只会发出警告.所以这就要求我们在实际的开发过程中一定要按照既定的规范来写代码。
多态的局限
父类指针不能直接调用子类独有的方法,虽然可以调用成功,但是这样写是不规范的
Animal *animal2 = [[Cat alloc] init]; [animal2 eat]; // [animal2 catchMouth];
多态的好处:
女孩一般比较喜欢养宠物,现在创建一个女孩类,让她拥有养宠物的方法
Girl.h
@class Animal; // 在Girl.h中用@class引入 Animal的头文件,告诉编译器后面的是一个类 @interface Girl : NSObject - (void)feedAnimal:(Animal *)animal; @end
Girl.m
#import "Animal.h" // 在Girl.m中用#import引入Animal的头文件 @implementation Girl - (void)feedAnimal:(Animal *)animal { NSLog(@"女孩饲养宠物%@", animal); }
@end
main.m
// 创建一个女孩对象 Girl *girl = [[Girl alloc] init]; // 前男友送了它一只猫cat,她需要饲养 Cat *cat = [[Cat alloc] init]; // 女孩对象调用饲养动物的方法,将猫传进去 [girl feedAnimal:cat]; // 现在,前男友把甩了,认识了新男友,新男友送了一只狗够给她,她也需要饲养 Dog *d = [[Dog alloc] init]; // 女孩对象调用饲养动物的方法,将狗传进去 [girl feedAnimal:d];
// 打印结果
2015-11-27 22:02:22.887 DuoTai[1812:401072] 女孩饲养宠物<Cat: 0x100206410>
2015-11-27 22:02:22.887 DuoTai[1812:401072] 女孩饲养宠物<Dog: 0x1003006c0>
多态的优点
猫和狗都是继承自Animal这个类,在这里我们就可以使用多态来简化代码了,只需要把函数的参数写成Animal * 类型的,那么Dog 和Cat类型的对象就可以传进来了,在调用的时候直接改变参数就可以了.
多态是面向对象编程的一个重要特征,它大大地增强了软件的灵活性和扩展性.