Protocol in Objective-C

来源:互联网 发布:wpf 数据绑定 编辑:程序博客网 时间:2024/05/23 00:06

前面提到了OOP的繼承,但不像C++可以有多重繼承,Objective-C是單一繼承的,如果想要做到一個類別同時擁有多種型別的能力,可以透過實作其它型別的interface來達成這個目的。在Java/AS3是用”interface”這個關鍵字,在Objective-C則是用”@protocol”。(有寫過Java/AS3的要特別注意不要把interface跟protocol搞混了,在Objective-C的interface等於Java/AS3的class,而protocol則是相當於interface)

直接來看看要怎麼做吧。如果你要新增一個自定的protocol的話,可以直接在你的專案裡新增一個protocol檔:

image

當然,你要全部寫在一起也沒人反對,只是為了模組化以及以後的可重複使用考量,建議獨立出來另外寫。新增完成之後(它是一個header檔),就可以開始來寫了,程式碼如下:

123456
@protocol Drawable-(void) draw;-(void) changeColor;@end

在Objective-C裡的protocol是用@protocol這個語法來定義的。在上面這段程式碼裡,我放了兩個方法,但沒有寫內容。接下來如果我要實作自這個protocol的話,所有定義在@protocol裡的方法都得實作出來。另外,在Objective-C 2.0之後加了@required@optional的語法,可以讓你設定這個method是不是必需一定要實作的項目。用法如下:

12345678910
@protocol Drawable@required-(void) draw;-(void) changeColor;@optional-(void) whateverMethod;@end

如果沒特別標明的,預設是@required。如果你要實作這個protocol的話,照英文字面來看,@required的部份是規定要實作的,@optional的話就隨你高興了。要注意的是@required跟@optional這兩個語法的影響範圍,是從它以下所有的method都會被影響,直到另一個directive或是@end為止,所以如果你要省略@required的話,記得那些method要寫在@optional前面。接下來來看看要怎麼實作這個protocol:

12345678910
#import <Cocoa/Cocoa.h>#import "Drawable.h"@interface Book : NSObject <Drawable>{  int price;}@property int price;@end

實作protocol的方法就是用”<>”標記,裡面放protocol的名稱。並不限定只能實作一個protocol,如果要實作多個protocol的話,則是用逗點分開:

1
@interface Book : NSObject <Drawable, Openable>

因為到目前為止,我們都還沒實作那個protocol裡定義的方法,所以這時候如果直接按下Build的話,就會跳出警告訊息:

image

接著來把該做的填一填吧。因為在protocol的地方已經有定義好了方法,所以在@interface的地方就不用再特別寫一次,只要在@implementation裡補上該實作的方法就行了。

1234567891011121314151617181920212223242526272829303132333435
// --------------// interface// --------------#import <Cocoa/Cocoa.h>#import "Drawable.h"@interface Book : NSObject <Drawable>{  int price;}@property int price;@end// --------------// implementation// --------------#import "Book.h"@implementation Book@synthesize price;// 實作方法draw-(void) draw{  NSLog(@"draw me!");}// 實作方法changeColor-(void) changeColor{  NSLog(@"change color!");}@end

如果你實作了所有@required的方法的話,則稱為遵守(conform)或採納(adopt)這個protocol(硬翻成中文還是覺得怪怪的,還是英文比較簡潔直接)。若要檢查某物件是否有乖乖遵守某個protocol的規定:

12345
Book *book = [[Book alloc] init];if ([book conformsToProtocol:@protocol(Drawable)] == YES){  NSLog(@"the book is conform to Drawable protocol");}

protocol本身也可以像一般類別的繼承,例如:

1234567
@protocol A-(void) methodA;@end@protocol B <A>-(void) methodB;@end

這時如果你要實作protocol B,則methodA跟methodB都需要實作。

另外,你也可以把protocol拿來當一般的型別定義來用,例如:

1
id <Drawable> some_object;

表示說這個some_object是個有實作Drawable這個protocol的物件,在編譯階段就可以先做型別檢查。當然也可以一次多個,一樣用逗點分開:

1
id <Drawable, Openable> some_object;

上面提到的這種用@protocol來定義方法的,稱做formal protocol,從名字看大概猜得出來一定也有叫做informal protocol的東西,不過這個會在category的部份再做說明。

转自:http://blog.eddie.com.tw/2010/12/11/protocol-in-objective-c/

0 0