Objective-C中的协议与Java、C#中的接口以及C++中的抽象类相类似,用于定义公共接口,并承诺类需要实现协议中规定的方法。
使用协议的最大好处就是它能够有效扩展程序的功能。举几个简单的例子,通用串行总线程(Universal Serial Bus,USB)就是一个协议,它能够让计算机周边设备连接标准化。现在的计算机都配备了USB接口,这样能够有效扩展计算机的功能。USB接口协议定义了接口尺寸、电压极性、电流大小、针脚位置等规范,只要设备符合USB协议就可以直接插入到计算机中使用。至于设备的具体作用可以由设备的生产厂家自己定义,例键盘、鼠标、游戏手柄、移动硬盘等。
Java、C#接口、C++抽象类要求实现它的非抽象类必须实现它规定的方法,而Objective-C中的协议更加灵活,它规定哪些方法必须实现,哪些方法可以有选择地实现。
1.声明协议
首先我们看一下如何创建协议。例如,我们希望通过一个协议来限制宠物应该满足的需求。向项目中创建一个文件,选取Objective-C protocol,并命名为Pet。
//Pet.h
@protocol Pet
@required
- (void)obedient:(NSString *)direction;
@optional
- (void)affectionate;
- (void)play;
- (void)sing;
- (void)dance;
@end
这段代码创建了一个名为Pet的协议。和类的外部接口声明类似,协议定义在@protocol与@end指令之间。@property后接协议名称,并使用@required与@optional指令分别指出哪些方法必须由采用该协议的类实现,哪些方法可以有选择性地实现,默认为@required。对于上述代码,方法obedient:是必须实现的,而方法affectionate、play、sing、dance可以实现,也可以不实现。通过定义协议Pet,要求所有宠物必须听话,但可以撒娇、玩、唱歌和跳舞。
2.实现协议
协议定义之后,需要其他类遵从(实现)协议。在类的外部接口中,可以定义类遵循从哪些协议。例如猫满足宠物的要求(暂时不考虑不听话的野猫和流浪猫),要在程序中反应这个信息,可以修改Cat类的外部接口,让其遵从Pet协议,添加如下代码:
//Cat.h
#import "Pet.h"
@interface Car : NSObject<Pet>
类不允许继承自多个类,但是类允许遵从多个协议,这与C#和Java是一致的。当某个类需要遵从多个协议时,可以在类的接口中的@interface指令后给出,协议名称必须位于尖括号内,多个协议名称之间使用逗号分隔。
Pet规定了一个必须实现的方法。如果Cat类不提供obedient:方法的实现。Xcode代码检查器会提示编译警告(注意不是错误,代码依然能够编译成功),
//Cat.m
- (void)obedient : (NSStirng *)direction {
NSLog(@"I'm a cute cat.You ask me %@ and I can understand is!", direction);
}