多态的概念:
不同对象以自己的方式相应相同名称方法的能力
多态的条件:
有继承关系,有方法重写
父类的声明变量指向了子类的对象
代码体现:
用父类类型的指针指向了子类对象,这就是多态
- Dog *dog = [Dog new];
- Animal *ani = [Dog new];
- Cat *cat = [Cat new];
- Animal *ani2 = [Cat newl];
-
优点:
简化了编程接口。容许在雷和类之间重用一些习惯性的命名
多态的实现:
- Dog *dog = [Dog new];
- Animal *ani = [Dog new];
- [ani run];
- 调用了Dog中的run方法
-
动态绑定:
动态类型能使程序直到执行时才确定对象的所属类型
注意:如果不存在多态,父类是不可以访问子类特有的方法事物
类的本质:
是个对象(类对象)是Class类型
类对象在程序运行时一直存在
类对象只能使用类方法,不能用实例方法
获取:通过实例对象获取
Dog *dog = [Dog new];
Class c = [dog class];
通过类名获取(类名就是类对象)
Class c2 = [Dog class];
类对象:
可以用来调用方法[Dog test]; [dog test];
可以用来实例化对象Dog *d1 = [Dog new];
存储细节:
SEL类型:
全称:selector 一种 用来表示方法名类型的数据类型(方法名)
作用:可以定义变量
可以用来作为方法的形参
可以用来作为方法的实参
Person *p = [Person new];
SEL sel = @selector(eat);
[p performSelector:@selector(eat)];
点语法:
- Student *stu = [[Student alloc] init];
- stu.age = 10; //等价于[stu setAge :10];
- int age = stu.age;//等价于int age = [stu age];
点语法,本质是:方法的调用,不是直接访问成员变量,编译器遇到时展开成相应的代码
点语法中不能用self 会进入死循环
@property用法
@property 类型 方法名
相当于进行了age的set和get方法的声明
@synthesize用法
@synthesize 类型 方法名
相当于进行了age的set和get方法的实现
- @synthesize int age;
- -(void)setAge:(int)age{
- _age = age;
- }
- -(int)age{
- return _age;
- }
@property 增强使用;
Xcode4.4 之后,可以只使用@property 而不用使用@synthesize ,此时声明和实现了 _age _name 的get/set 方法,操作的带下划线的实例变量; 如果我们当前类没有下划线的实例变量,则系统会帮我们生成;但是生成的_age _name 都是私有的,不能被子类继承和访问;
在@property 下重写 get/set 方法;
只有@property 时,get/set 方法只能重写一个,两者同时重写时会报错!
动态类型和静态类型:
多态:允许不同的类定义相同的方法
动态类型:程序直到执行时才确定所属的类
静态类型:讲一个变量定义为特定类的对象时,使用的静态形态
使用动态,编译时编译器会自动跳过,不进行检查,提高了代码的编译速度,只有在运行时才会仔细查找
id 类型
id是一种通用对昂类型,他可以用来存储属于任何类的对象 (万能指针)
id和instancetype的异同
相同点:都可以作为方法的返回类型
不同点:@instancetype可以返回和方法所在类相同类型的对象id只能返回未知类型的对象
@instancetyep只能作为返回值,不能像id那样作为参数
动态类型检测
动态绑定:一个对象是否能调用指定的方法不是有编译器决定的而是由运行时决定的
检测方法:
判断类型
-(BOOL)isKindOfClass:classObj 判断实例对象是否是这个类或者这个类的子类的实力对像
- Animal *ani = [Animal new];
- Dog *dog = [Dog new];//继承Animal
- BOOL b = [ani isKindOfClass:[Animal class]];
- //判断ani是否是Animal类的对象
- b = [dog isKindOfClass:[Animal class]];
- //判断dog 是否是Animal类或子类的对象
-(BOOL)isMemberOfClass:classObj 判断是否是这个类的实例,不管是否是这个类的子类的实例
- Dog *dog = [Dog new];
- Animal *ani = [Dog new];
- [ani run];
- 调用了Dog中的run方法
+(BOOL)isSubclassOfClass:classObj 判断类是否是制定类的子类
- Dog *dog = [Dog new];
- Animal *ani = [Dog new];
- BOOL b = [Animal isSubclassOfClass:[dog class];
- //判断Animal是否是当前类的子类
判断对象是否能相应指定的方法
-(BOOL)respondsToSelector:selector 判断实例是否有这样的方法能响应
- SEL s1 = @selector(run);
- BOOL b = [dog respondsToSelector:s1];
-(id)performSelector:selector(应用selector指定的方法)
- SEL s1 = @selector(run);
- [dog performSelector:s1];
-(id)performSelector:selector withObject:object(应用selector指定的方法传入参数object)
- SEL s1 = @selector(run);
- [dog performSelector:s1];
- [dog performSelector@selector(eat:andFoot:)withObject:str1 withObect :str2];