Objective-C關於協議protocol與代理degelate以及protocol的型別限制
在學習oc的過程中,協議以及代理的概念遇上一些問題,現在終於理清了,所以在這裡分享下
先看下概念:
-
Protocol翻譯過來, 叫做”協議”
- 在寫java的時候都會有介面interface這個概念,介面就是一堆方法的宣告沒有實現,而在OC裡面Interface是一個類的標頭檔案的宣告,並不是真正意義上的介面的意思,在OC中介面是由一個叫做協議的protocol來實現 的
- protocol它可以宣告一些必須實現的方法和選擇實現 的方法。這個和java是完全不同的
-
Protocol的作用
- 用來宣告一些方法
- 也就說, 一個Protocol是由一系列的方法宣告組成的
假設我們要踢球,運動員有踢的動作,然後球就會飛起來
分析下,這應該包含兩個類,運動員和球,運動員踢球的動作就相當於委託代理球自己飛起來,踢的動作相當於一個出發點。
首先,我們需要建立一個協議,Command+N,選擇Objective-C File,File Type選擇protocol。
這是協議myProtocol的檔案
#import <Foundation/Foundation.h>
//定義一個協議
@protocol footballProtocol <NSObject>
//協議不能包含成員變數
//定義協議方法
@required
//required關鍵字表示該方法必須實現,不實現不會報錯但是會報警告,預設是required
-(void)fly;
@optional
//optional表示該方法可以選擇實現或者不實現,不會報錯不會報警告也
-(void)goalScore;
@end
有了協議,咱們就需要類來去遵守這個協議,相當於java中定義了interface介面就要有implementation實現介面接下來建立球類Command+N 選擇cocoa class
定義球類ball的宣告檔案
#import <Foundation/Foundation.h>
#import "footballProtocol.h"
//宣告類ball遵守協議footballProtocol
@interface ball :
//宣告球類旋轉的方法
-(void)rotate;
@end
實現協議myProtocol和ball非正式協議自身的方法,在ball.m中去操作#import "ball.h"
@implementation ball
//ball自身的方法
-(void)rotate{
NSLog(@"我轉,我一直轉!!!");
}
//遵守協議實現的方法
-(void)fly{
NSLog(@"飛向球門,go!!!");
}
-(void)goalScore{
NSLog(@"進球啦,得分了!!!");
}
@end
接下來我們應該建立運動員類player,player類要讓球類ball替自己去完成飛的動作,首先就需要也遵守footballProtocol協議,還需要設定屬性返回一個遵守該協議的物件,注意,delegate並不是關鍵詞,可以用其他單詞。#import <Foundation/Foundation.h>
#import "footballProtocol.h"
//定義player遵守footballProtocol協議
@interface player : NSObject<footballProtocol>
//設定屬性要遵守協議的物件
@property(nonatomic,strong) id<footballProtocol> delegate;
//player自身的方法
-(void)eat;
@end
player類同樣遵守協議,對於協議中@required的方法必須實現,下面是player.m檔案#import "player.h"
@implementation player
@synthesize delegate=_delegate;
-(void)eat{
NSLog(@"踢球要補充能量,趕緊吃吃吃!!!");
}
//實現方法通過代理去呼叫ball實現的方法
-(void)fly{
[_delegatefly];
}
-(void)goalScore{
[_delegategoalScore];
}
@end
最後的main檔案是見證奇蹟的時刻#import <Foundation/Foundation.h>
#import "ball.h"
#import "player.h"
int main(int argc, constchar * argv[]) {
@autoreleasepool {
// insert code here...
//例項化物件並初始化
ball *b=[[ballalloc]init];
player *p=[[playeralloc]init];
//設定代理
p.delegate=b;
[p eat];
[p fly];
[b rotate];
//代理物件的方法只能自己去呼叫
[p goalScore];
}
return0;
}
執行的結果如圖