黑马程序员——ObjectiveC基础——多态与id类型
2015-10-18 02:10
579 查看
——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
一、概述
定义:不同对象用自己的方式相应相同的名称的方法的能力叫做多态
多态的本质是动态绑定,程序知道执行时才确定对象所属的类型,是父类指向子类的指针。
优点:把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。 赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。
二、多态的代码实现
动物类Animal有方法run,狗类Dog继承了Animal类,并重写了run方法,添加了新的方法eat
Animal.h
Animal.m
Dog.h
Dog.m
main.m
说明:
多态中,当子类调用父类中不存在的方法时(即子类新增加的方法),无法通过编译,在编译过程中报错。需要将值类型转换才能通过编译,并可以成功运行。
错误示例:
说明:栈中的a2指针指向的是堆中的Animal的类,其中的_isa指针指向的是Animal类在代码区中存放的代码,这些代码中并没有eat方法。之所以可以通过编译时因为强制类型转换成Dog类型后,“欺骗”了编译器,使得编译器无法察觉错误。
三、通过NSObject实例化对象
所有类都继承自NSObject,可以说NSObject是所有类的基类,可以通过NSObject实例化任何类。
四、id类型
id是一种通用的对象类型,他可以用来存储任何类的对象。也可以理解为万能指针。
id的定义中已经包含了*号, 指针定义变量时,不需要再加* 号。
ios5之后推出了instancetype类型,与id类型相比:
1.都可以作为方法的返回值类型
2.instancetype可以返回和方法所在类相同类型的对象,id只能返回位置类型的对象。
3.instancetype只能最为返回值,不能作为参数,而id可以。
需要注意的是,和NSObject相比,通过id创建的对象不需要强制类型转换就可通过编译。
一、概述
定义:不同对象用自己的方式相应相同的名称的方法的能力叫做多态
多态的本质是动态绑定,程序知道执行时才确定对象所属的类型,是父类指向子类的指针。
优点:把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。 赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。
二、多态的代码实现
动物类Animal有方法run,狗类Dog继承了Animal类,并重写了run方法,添加了新的方法eat
Animal.h
#import <Foundation/Foundation.h> @interface Animal : NSObject -(void) run; @end
Animal.m
#import "Animal.h" @implementation Animal -(void) run{ NSLog(@"动物在跑..."); } @end
Dog.h
#import "Animal.h" @interface Dog : Animal -(void) run; -(void) eat; @end
Dog.m
#import "Dog.h" @implementation Dog -(void) run{ NSLog(@"狗在跑..."); } -(void) eat{ NSLog(@"狗在吃东西..."); } @end
main.m
#import <Foundation/Foundation.h> #import "Animal.h" #import "Dog.h" int main(int argc, const char * argv[]) { @autoreleasepool { // insert code here... Animal *a = [Dog new]; [a run]; //输出:狗在跑... //[a eat]; //报错(原因是Animal类没有eat方法,必须经过强制类型转换才能通过编译) [(Dog *)a eat]; //输出:狗在吃东西... } return 0; }
说明:
多态中,当子类调用父类中不存在的方法时(即子类新增加的方法),无法通过编译,在编译过程中报错。需要将值类型转换才能通过编译,并可以成功运行。
错误示例:
#import <Foundation/Foundation.h> #import "Animal.h" #import "Dog.h" int main(int argc, const char * argv[]) { @autoreleasepool { Animal *a2 = [Animal new]; [(Dog *) a2 eat]; //可以通过编译,但是运行时报错。 } return 0; }
说明:栈中的a2指针指向的是堆中的Animal的类,其中的_isa指针指向的是Animal类在代码区中存放的代码,这些代码中并没有eat方法。之所以可以通过编译时因为强制类型转换成Dog类型后,“欺骗”了编译器,使得编译器无法察觉错误。
三、通过NSObject实例化对象
所有类都继承自NSObject,可以说NSObject是所有类的基类,可以通过NSObject实例化任何类。
#import <Foundation/Foundation.h> #import "Animal.h" #import "Dog.h" int main(int argc, const char * argv[]) { @autoreleasepool { NSObject *b = [Dog new]; [(Dog *) b eat]; //输出:狗在吃东西... } return 0; }
四、id类型
id是一种通用的对象类型,他可以用来存储任何类的对象。也可以理解为万能指针。
id的定义中已经包含了*号, 指针定义变量时,不需要再加* 号。
ios5之后推出了instancetype类型,与id类型相比:
1.都可以作为方法的返回值类型
2.instancetype可以返回和方法所在类相同类型的对象,id只能返回位置类型的对象。
3.instancetype只能最为返回值,不能作为参数,而id可以。
#import <Foundation/Foundation.h> #import "Animal.h" #import "Dog.h" int main(int argc, const char * argv[]) { @autoreleasepool { id obj = [Dog new]; [obj eat]; //输出:狗在吃东西... } return 0; }
需要注意的是,和NSObject相比,通过id创建的对象不需要强制类型转换就可通过编译。
相关文章推荐
- 黑马程序员——ObjectiveC基础——构造方法和自定义构造方法
- 完美解决水晶报表的翻页问题
- Object-C自定义对象NSLog输入信息
- 黑马程序员——ObjectiveC基础——NSString对象
- 黑马程序员——ObjectiveC基础——对象关系
- 黑马程序员——ObjectiveC基础——Self与Super
- [Albert的专栏]★★objective-c面向对象之——类的继承
- OC学习NSString与NSMutableString字符串
- objective-c 中随机数的用法 (3种:arc4random() 、random()、CCRANDOM_0_1() )
- OC学习NSArray与NSMutableArray数组
- Objective-C中的instancetype和id关键字
- Objective-C:自定义Block函数
- Objective-C:三种文件导入的方式以及atomic和nonatomic的区别
- Objective-C内存管理中的Retain Circle
- Objective-C开发-条件编译
- Objective-C 入门笔记
- NSNumber与NSInteger的区别
- NSArray方法 Objective-c
- 【IOS 开发学习总结-OC-29】★★objective-c之foundation 框架——(集合类)数组
- iOS Object-c 学习笔记