协议(Protocal)
协议 声明了任何类都可以实现的编程接口. 这就使得两个继承关系很远的类也能够相互通信, 几乎所有的对象都继承于NSObject
, 也就是说, 这些对象都可以使用协议来相互通信.
这是替换子类化的一种选择.为什么这么说呢? 答案如下:
一个类可以给其它类提供有用的行为, 它就可以声明一个接口, 使用协议来出售
行为. 其它任何类都可以采用这个协议,并实现其中的一个或多个方法, 从而使用该行为. 这实际上就可以实现子类化的功能, 即不同的类使用同一个接口, 却可以有不同的行为.

协议可以分为正式协议(Formal
)和非正式协议(Informal
)
-
正式协议: 声明了客户端类要实现的方法列表. 正式协议有自己的声明、采用 和 类型检查语法, 可以通过关键字
@required
和@optional
分别设置方法是必须要实现的还是可选的(默认是@required
). 子类可以继承父类采用的正式协议. 正式协议也可以采用其它协议. -
非正式协议: 是
NSObject
的分类或类别, 隐式地使几乎所有对象都采用该协议.(类别是一个语言特性:可以不用继承类,而给该类添加方法), 非正式协议中的方法都是可选(optional
)的. 在optional
引入之前,Foundation
和AppKit
都靠非正式协议来实现代理.
采用协议: 在类的接口使用<protocal>
来采用正式协议, 多个协议用,
分隔, 如下所示:
@interface CAAnimation : NSObject <NSCopying, CAMediaTiming, CAAction>
遵守协议: 除了采用协议外, 还要实现正式协议中必须(required
)实现的方法. 如果继承于一个已遵守协议的类, 则该子类也被认为是遵守了该协议.
// 声明协议
@protocol Protocal <NSObject>
@optional
- (void)func1;
@required
- (void)func2;
@end
//A 类采用该协议, 并实现required
的方法 来 遵守协议
@interface ModelA : NSObject <Protocal>
@end
@implementation ModelA
- (void)func2 {
NSLog(@"11 %@", self);
}
@end
//B 类采用该协议, 并实现required
的方法 来 遵守协议
@interface ModelB : NSObject <Protocal>
@end
@implementation ModelB
- (void)func2 {
NSLog(@"22 %@", self);
}
@end
//B的子类 因B类遵守协议, 而遵守协议
@interface ModelSubB : ModelB
@end
@implementation ModelSubB
@end
// 分别调用协议方法
ModelA *objA = [ModelA new];
[objA func2];
ModelB *objB = [ModelB new];
[objB func2];
ModelSubB *objSubB = [ModelSubB new];
[objSubB func2];
//输出如下:
11 <ModelA: 0x600002cc86b0>
22 <ModelB: 0x600002cc86d0>
22 <ModelSubB: 0x600002cc86a0>
网友评论