多态就是事物的多种表现形态
在编译的时候编译器只会检查当前类型对应的类中有没有需要调用的方法,在运行时,系统会自动判断对象的真实类型
多态的原理
- 动态绑定
- 动态类型能时程序直到执行的时候才确定对象的真实类型
- 动态类型绑定能使程序直到执行时才确定要对哪个对象调用方法
- OC不同于传统程序设计语言,它可以在运行时加入新的数据类型和新的程序模块:动态类型识别、动态类型绑定、动态加载
- id类型:通用对象指针类型,弱类型,编译时不进行具体类型检查
注意点:
在多态中,如果想调用子类特有的方法必须强制类型转换为子类才能调用
例子:
- 定义一个动物类Animal,然后定义一个猫类Cat,狗类Dog分别继承动物类Animal
- 分别实例化Cat类和Dog类,对象使用Animal定义
main.h
#import <Foundation/Foundation.h>
#import "Cat.h"
#import "Dog.h"
#import "Animal.h"
int main(int argc, const char * argv[]) {
// 使用Animal类实例化Cat类
Animal *cat = [Cat new];
// cat对象目前是Animal类型,当程序真正执行的时候,会去查看cat的真实类型,然后会先从Cat类中查找是否存在setName方法,如果不存在,在去Cat的父类中去查找
[cat setName:@"猫"];
Animal *dog = [Dog new];
[dog setName:@"狗"];
[cat eat:cat];
[dog eat:dog];
return 0;
}
Animal.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Animal : NSObject
{
NSString *_name;
}
- (void)setName:(NSString *)name;
-(void)eat:(Animal *)a;
@end
NS_ASSUME_NONNULL_END
Animal.m
#import "Animal.h"
@implementation Animal
-(void)eat:(Animal *)a{
NSLog(@"给%@喂食物", a->_name);
}
- (void)setName:(NSString *)name{
_name = name;
}
@end
Dog.h
#import <Foundation/Foundation.h>
#import "Animal.h"
NS_ASSUME_NONNULL_BEGIN
@interface Dog : Animal
@end
NS_ASSUME_NONNULL_END
Dog.m
#import "Dog.h"
@implementation Dog
@end
Cat.h
#import <Foundation/Foundation.h>
#import "Animal.h"
NS_ASSUME_NONNULL_BEGIN
@interface Cat : Animal
@end
NS_ASSUME_NONNULL_END
Cat.m
#import "Cat.h"
@implementation Cat
@end