協定
前言
我們之前講過非正式協定(NSOject的類目),那麼肯定還有正式協定。
在OC中,一個類可以實作多個協定,通過協定可以彌補單繼承的缺陷,但是協定跟繼承不一樣,協定隻是一個方法清單,方法的實作得靠遵循該協定的類去完成。
概念
協定:協定是一套标準,這個标準裡面聲明了很多方法,但是不關心具體這些方法是怎麼實作的,具體的實作是由遵循這個協定的類去完成的
下面我們通過學生和外賣員這個例子來說明:
正式協定用 @protocol 來定義
在方法聲明的時候,可以有兩個關鍵字去限制是否讓遵循該協定的類去實作該方法
@required :标注的方法為必須實作的方法(預設的)
@optional :标注的方法為可選實作的
(協定寫在.h檔案中的@interface上面或外置建立一個協定檔案)
@protocol FoodProtocol <NSObject>
@required
-(void)sendFood:(BOOL)flag;
@optional
-(void)sayHello;
@end
@interface Student : NSObject
@property (nonatomic,assign)BOOL flag;
@property (nonatomic,assign)id<FoodProtocol> delegate;
@end
在Student.m檔案中中:
@implementation Student
-(void)setFlag:(BOOL)flag{
_flag = flag;
//conformsToProtocol: 确定了一個對象是否實作了某個協定
//如果代理存在并且代理遵循了某個協定,就傳回YES
if (self.delegate &&[self.delegate conformsToProtocol:@protocol(FoodProtocol) ]) {
[self.delegate sendFood:_flag];
}
else{
NSLog(@"代理不存在");
}
}
@end
在Waiter.h檔案中,對協定FoodProtocol進行聲明:
#import <Foundation/Foundation.h>
#import "Student.h"
@interface Waiter : NSObject<FoodProtocol>
@end
在Waiter.m檔案中,實作協定中必須實作的方法:
#import "Waiter.h"
@implementation Waiter
-(void)sendFood:(BOOL)flag{
if (flag) {
NSLog(@"我給你送外賣");
}
else{
NSLog(@"學生不忙,你自己過來拿");
}
}
@end
其實學生送外賣這個例子,同時也是一個委托模式的例子,會在我們接下來的學習中學到。