多态:相同的名称,不同的类
使不同的类共享相同方法名称的能力成为多态。它让你可以开发一组类,这组类中的每一个类都能响应相同的方法名。每个类的定义都封装了响应特定方法所需要的代码,这使得它独立于其他的类定义。这是因为Objective-C的运行时系统在执行方法时知道消息的接收者是哪个类的对象,它总是携带有关“一个对象属于哪个类”这样的信息,该信息能使系统在运行时做出决定,而不是在编译时。
动态绑定和id类型
id数据类型是一种通用的对象类型,可以用来存储属于任何类的对象。当使用id类型的时候,程序的一些测试被从编译时推迟到了运行时进行,因为在编译时系统还无法确定这个数据类型究竟是什么类型的。
如果使用动态类型来调用一个方法,需要注意一下规则:如果在多个类中实现名称相同的方法,那么每个方法都必须符合各个参数的类型和返回值类型,这样编译器才能为消息表达式生成正确的代码。
Objective-C中的类都继承自NSObject类,而这个类支持一些方法,可以用来避免错误或在程序运行时检查程序的完整性,如下:
方法 | 问题或行为 |
-(BOOL) isKindOfClass: class-object | 对象是不是class-object或其子类的成员 |
-(BOOL) isMemberOfClass: class-object | 对象是不是class-object的成员 |
-(BOOL) respondsToSelector: Selector | 对象是否能够响应selector所指定的方法 |
-(BOOL) instancesRespondToSelector: Selector | 指定的类实例能否响应selector |
-(BOOL) isSubclassOfClass: class-object | 对象是否是指定类的子类 |
-(BOOL) performSelector: Selector | 应用selector指定的方法 |
-(BOOL) performSelector: Selector withObject: object | 应用selector指定的方法,传递参数object |
-(BOOL) performSelector: Selector withObject: object1 withObject: object2 | 应用selector指定的方法,传递参数object1和object2 |
这样在id类型对象上调用某方法之前,就可以先进行一些判断,来阻止可能产生的错误和崩溃。
此外,也可以采用其他策略如使用 forwardInvocation: 方法将消息转发给其他对象处理。
在实际开发中也可以通过协议来对id类型做一些约束,这样编译器就能提前知道方法调用是否正确。