Obj-C的多态性、动态类型和动态绑定

Obj-C是一门强大的面向对象的编程,因此它具有面向对象的很多特征,比如多态性,支持动态类型和动态绑定。我们来分别学习一下:

1. 多态性

多态性是个生物名词,用来表示生物体在生命周期中的不同形态,用在编程语言中则表示相同的方法名,但是却有不同的实现方式。或者说相同的名字,不同的类。我们来看一个书上的示例:

01 #import <Foundation/Foundation.h>
02 //定义类 A
03 @interface A : NSObject
04 -(void)print
05 @end
06 @implementation
07 -(void)print
08 {
09     NSLog(@"this is Class A");
10 }
11 @end
12  
13 //定义类 B
14 @interface B : NSObject
15 -(void)print
16 @end
17 @implementation
18 -(void)print
19 {
20     NSLog(@"this is Class B");
21 }
22 @end
23  
24 int main(int argc, char *argv[])
25 {
26     NSAutoreleasePool * pool=[[NSAutoreleasePool alloc] init];
27     A *a=[[A alloc] init];//实例化类A对象
28     B *b=[[B alloc] init];//实例化类B对象
29     [a print];          //调用类A的print方法
30     [b print];          //调用类B的print方法
31      
32     [a release];        //释放实例a
33     [b release];        //释放实例b
34     [pool drain];
35      
36     return 0;
37 }

程序的最终输出结果如下:

this is Class A

this is Class B

那么类A和类B都包含了print方法,那么系统怎么知道什么时候调用哪个方法呢?因为Obj-C运行环境时支持类型检查,知道类A是print消息的第一个接收者,类B是第二个接收者,那么也就是同一个方法名有不同的类实现,我们称之为多态性。

2. 动态绑定和动态类型

id是公用的对象类型,它可以用来存放任何类的对象,那么我们就再来看一个如何运用id实现动态绑定的例子:

01 int main(int argc, char *argv[])
02 {
03     NSAutoreleasePool * pool=[[NSAutoreleasePool alloc] init];
04     id temObj;            //声明一个id类型
05     A *a=[[A alloc] init];//实例化类A对象
06     B *b=[[B alloc] init];//实例化类B对象
07      
08     temObj=a;             //将a对象赋值给temObj
09     [temObj print];       //调用类A的print方法
10      
11     temObj=b;             //将b对象赋值给temObj
12     [temObj print];       //调用类B的print方法
13      
14     [a release];        //释放对象a
15     [b release];        //释放对象b
16     [pool drain];
17      
18     return 0;
19 }

在上面的代码中我们可以看到temObj被声明为id类型,因此它可以存放任何类型的对象,当temObj存放类A的对象a时,我们就可以通过temObj调用类A的全部方法,同样,当temObj存放的类B的对象b时,我们也可以通过temObj来访问类B的全部方法。

那么,程序是如何知道我们要调用哪一个类的print方法呢?很简单,因为Obj-C在运行时,环境会一直对“对象属于哪个类”进行追踪,基于动态类型和动态绑定的概念,系统会对对象的类作出正确的决定,系统会在运行的时候而不是编译的时候决定调用哪一个方法。

下面是Object类确认对象类型的基础API:

确认类型API表
方法 功能
-(BOOL)isKindOfClass:class-object判断对象是否是某一种类(包括其父类)的实例
-(BOOL)isMemberOfClass:class-object判断对象是否是某一种类(不包括其父类)的实例
-(BOOL)respondsToSelector:selector判断对象是否有实现某个方法
+(BOOL)instancesRepondToSelector:selector判断类的实例是否有实现某个方法
+(BOOL)isSubclassOfClass:class-object判断一个类是否是某个类的子类
-(id)performSelector:selector让对象调用指定的方法
-(id)performSelector:selector withObject: object让对象调用指定的方法并且带一个参数
-(id)performSelector:selector withObject: object1 withObject: object2让对象调用指定的方法并且带两个参数

上面的表格中提到了常用的api方法,那么在程序中我们可以灵活使用这些api来方便地实现各种动态编程语言特性,使得Obj-C拥有了很多动态脚本语言才有地特性
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值