http://blog.csdn.net/braddoris/article/details/24620199
1. ObjC中不支持多重继承,但可以使用协议和分类来实现多重继承的效果。
(在java和c#中也没有多重继承的概念,取而代之的是接口,而在我们ObjC中我们使用的是协议和分类,类似于c++中的抽象类)
2.协议不是一个真正的类:它只能声明方法而不能有任何实例变量,它有两种类型:正式协议和非正式协议,并且协议只有声明文件,没有实现文件。
3.正式协议与非正式协议区别
正式协议是方法的集合,遵循了正式协议的类中必须要实现协议中的所有方法。一个类可以遵循的协议数量没有限制。
非正式协议也是一系列方法的集合,但是遵循非正式协议中的类中可以根据自己的需要选择实现协议中的方法,即非正式协议中的方法可以不实现。
在《Cocoa设计模式》第六章类别的6.3.2把类别用于非正式协议一节中,这样写到:
非正式协议通常定义为NSObject的类别。类别接口中指定的方法可能会或者可能不会被框架类实际地实现。非正式协议位于一种设计灰区中。正式协议由编译器检查并且代表一种关于对象能力的保证,但是非正式协议不会做出保证----而只会给出提示。
苹果官方文档Cocoa Core Competencies一文中是这样介绍非正式协议的:
An informal protocol is a category on NSObject, which implicitly makes almost all objects adopters of the protocol. (A category is a language feature that enables you to add methods to a class without subclassing it.) Implementation of the methods in an informal protocol is optional. Before invoking a method, the calling object checks to see whether the target object implements it. Until optional protocol methods were introduced in Objective-C 2.0, informal protocols were essential to the way Foundation and AppKit classes implemented delegation.
大概意思:非正式协议是NSObject类(显而易见,还包括它的子类)的类别,其所有的子类都含蓄地接受了这个协议。(类别是Objective-C的一个语言特点,可以让你在无需子类化的前提下为一个类增加方法。)非正式协议中的方法是否实现都是可选的,因此在调用非正式协议中的方法之前,需要去检查对象类是否实现了它。在Objective-C2.0中引入可选的正式协议方法之前,非正式协议是Foundation和AppKit类实现委托的唯一方式。
综合1、2两段引文可以看出,所谓的非正式协议就是类别,即凡是NSObject或其子类的类别,都是非正式协议。
正式协议从概念上理解起来就简单的多了,它指的是一个以@protocol方式命名的方法列表,与非正式协议相比不同的是,它要求显示的采用协议
4.正式协议存在的意义
从字面上理解,正式协议比非正式协议要正式了很多,它存在的意义在于:
正式协议可以将业务中的方法定义剥离出来,形成一个单独的文件,这跟传统OO中的提取接口是不谋而合的。如果遇到二个系统需要交换数据,可以制定一套双方都遵守的协议,然后这二个系统中都把这个协议文件添加到项目中,实现它即可
- 5.格式
- ¬ 协议的编写
@protocol 协议名称
// 方法声明列表
@end
- ¬ 某个类遵守协议
@interface 类名 : 父类 <协议名称>
@end
协议中有2个关键字可以控制方法是否要实现(默认是@required),在大多数情况下,用途在于程序员之间的交流
- ¬ @required:这个方法必须要实现(若不实现,编译器会发出警告)
- ¬ @optional:这个方法不一定要实现
- 4. 协议遵守协议
- ¬ 一个协议可以遵守其他多个协议,多个协议之间用逗号 , 隔开
- ¬ 一个协议遵守了其他协议,就相当于拥有了其他协议中的方法声明
- @protocol 协议名称 <协议1, 协议2>
- @end
- 定义变量时指定协议
- // NSObject类型的对象,并且要遵守NSCopying协议
- NSObject<NSCopying> *obj;
- // 任何OC对象,并且要遵守NSCoding协议
- id<NSCoding> obj2;
- λ 协议通常是不与任何类有特定的关联,只是为所有的类提供了一个公有的接口
- λ 协议定义没有对应的实现部分,在遵循协议的类中实现协议中的方法,如果类遵循了多个协议,协议之间用,隔开,实现的协议中的方法是可以继承的。
- 5.NScopying协议
- 我们使用copy时,系统会执行copyWithZone:方法,copyWithZone这个方法在NSCopying协议中,即我们AddressBook类需要遵循NSCopying协议,实现协议中的copyWithZone:方法
- 如果你想要实现可变拷贝的,你可以遵循NSmutableCopying协议,实现协议中的mutableCopyWithZone:方法。如果你两个协议都遵循了,那么实现copyWithZone:方法时应该返回一个不可变的对象,如果实现mutableCopyWithZone:则应返回的一个可变的对象。
- λ 给你个不可变的对象创造一个可变的对象副本是合法的,也就是说,对象本身不可变,但是我们可以通过向它发送mutableCopy生成一个可变的对象。
- λ 如果让类遵循NSCopying协议,则声明文件如下:
- @interface XYPoint: NSObject <NSCopying>
- λ 这就表示XYPoint继承自NSObject并且遵循了NSCopying协议。既然此类遵循了NSCopying协议,那么在实现文件中就需要实现类中的方法copyWithZone:,方法实现如下:
- -(id) copyWithZone:(NSZone *) zone //NSCoping协议中的正式方法
- {
- XYPoint * newPoint =[[XYPoint allocWithZone: zone] init];
- [newPoint setX: x andY: y];//将就对象的实例变量拷贝到新对象中
- //x和y:是要被拷贝的旧对象的实例变量。
- return newPoint;//返回新对象
- }
- zone是NSZone的对象,当优化内存时使用。我们向一个对象发送copy消息时实际上给copyWithZone:方法传了nil。如果你的程序中alloc了大量的内存,并且你向要优化你的内存区域,你可以给copyWithZone:传值,使用allocWithZone:来开空间,这个方法可以在指定的区域开辟空间。
- 在上边实现的copyWithZone:方法中首先创建了新的XYPoint对象,之后把copy的receiver的x和y的值赋给新对象的x和y,最后把新对象返回赋给左值
- 6.基协议
- 所有类都遵守了基协议(基类遵守基协议)
- NSObject是一个基类,最根本最基本的类,任何其他类最终都要继承它
- 其实还有一个协议,名字也叫NSObject,它是一个基协议,最根本最基本的协议
- NSObject协议中声明很多最基本的方法,比如description、retain、release等
- 建议每个新的协议都要遵守NSObject协议
- 7.协议用于设计模式
- 代理模式 观察者模式