------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一、多态的概念
1、什么是多态?
多态指的是:同一种行为,对于不同的事物具有不同的表现形式。这就叫做多态。
举个例子:
老师给你布置1个任务,让你给老师找了3个人来。结果你给老师找了1个医生,1个演员,1个理发师。 请问这样可以吗?当然可以,医生、演员、理发师他们都是人,完全符合老师的要求。好了,现在我向他们发出1个指令,我说你们都给cut. 让他们都去执行cut这个行为。
医生会做什么?拿着手术刀就给你开刀。
演员会做什么?立即停止表演,等着发盒饭。
理发师会做什么?拿起剪刀就要给你剪头发。
看到了吗?这3个人对于同1个行为(cut). 具有不同的表现形式 这就叫做多态。
现实生活中多态的特点:
1).在老师的眼里,他们三个我只当做人来看待。
2).三个人具有共同的行为,但是他们每1个人的这个行为的实现是不一样的。
3).给他们发送这个指令然后每1个人按照自己的实现方式去做。
程序中的多态:不同的对象以自己的方式响应相同名称方法的能力称为多态
2、多态的条件
多态的条件:有继承关系、有方法重写
父类的声明变量指向子类对象。
//代码体现:用父类类型的指针指向了子类对象,这就是多态
狗*g = [狗new];
动物*a = [狗new];
猫*c = [猫new];
动物*a = [猫new];
3、多态的优点
多态的主要好处就是简化了编程接口。它容许在类和类之间重用一些习惯性的命名,而不用
为每一个新加的函数命名一个新名字。这样,编程接口就是一些抽象的行为的集合,从而和实现
接口的类的区分开来。
多态也使得代码可以分散在不同的对象中而不用试图在一个函数中考虑到所有可能的对象。
这样使得您的代码扩展性和复用性更好一些。当一个新的情景出现时,您无须对现有的代码进行
改动,而只需要增加一个新的类和新的同名方法。
二、多态的实现
1、如何实现多态?
Animal是父类,子类有Cat 和 Dog,子分别重写了父类中的eat方法;实例化对象的时候可以用下面的方法:
Animal *animal = nil;
//实例化猫的对象
animal = [Cat new];
[animal eat];
//实例化狗的对象
animal = [Dog new];
[animal eat];
创建一个类:
#import<Foundation/Foundation.h>
@intface Animal : NSObject
-(void)run;
@end
实现这个类
#import"Animal.h"
@implementation Animal
-(void)run{
NSLog(@"动物在跑");
}
创建两个子类:Dog和Cat
#import<Foundation/Foundation.h>
@intface Dog : Animal
-(void)run; //此处可以不用写
@end
实现Dog类:
#import"Dog.h"
@implementation Dog
-(void)run{
NSLog(@"狗再跑");
}
Cat类:
#import<Foundation/Foundation.h>
@intface Cat : Animal
-(void)run; //此处可以不用写
@end
实现Cat类:
#import"Cat.h"
@implementation cat
-(void)run{
NSLog(@"猫在跑");
}
main函数实现:
#import <Foundation/Foundation.h>
#import "Animal.h"
#import"Dog.h"
#import"Cat.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
/*****************没有使用多态的情况**/
Animal *ani = [Animal new];
[ani run];
Dog *dog = [Dog new];
[dog run];
Cat *cat = [Cat new];
[cat run];
/*****************使用多态的情况,父类指针指向了子对象**/
Animal *a2 = [Dog new];
[a2 run];
Animal *a3 = [Cat new];
[a3 run];
}
return 0;
}
2、多态的原理
动态绑定:
动态类型能使程序直到执行时才确定对象所属类型
动态类型绑定能使程序直到执行时才确定要对对象调用的实际方法
OC不同于传统程序设计语言,它可以再运行时加入新的数据类型和新的程序模块:动态类型识别,动态绑定,动态加载
id类型:通用指针类型,弱类型,编译时不进行类型检查
3、多态的注意点
1)如果存在多态,父类是可以访问子类特有的方法
如:
@intface Dog : Animal
-(void)run; //此处可以不用写
-(void)bark; //子类特有的方法
@end
实现:
@implementation Dog
-(void)run{
NSLog(@"狗再跑");
}
-(void)bark
{
NSLog(@"狗在叫");
}
在main 中:
#import <Foundation/Foundation.h>
#import "Animal.h"
#import"Dog.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Animal *an2 = [Dog new];
[(Dog*)an2 bark]; //把父类的指针,强制类型转换,从而父类访问子类方法
}
return 0;
}
2)如果不存在多态,父类是不可以访问子类特有的方法的
Animal *an3 = [Animal new];
[(Dog*)an3 bark]; //错误的,不能强制转换