objective-c中的protocol跟java中的介面interface和c++中的純虛類(purely virtual class)一樣,本質都是用於一個類需要遵循的某個通訊協定,從這個意義上看,
objective-c的協議說法可能更加恰當。
一,如何定義protocol?
protocol的定義非常簡單,基本遵循以下的格式即可:
@protocol ProtocolName
//Here is protocol method list that you must implement
@end
二,protocol如何使用?
某個類要遵循(conforms)某個protocol,將要遵循的protocols放到<>裡面,並且多個protocol用逗號分開,如下:
@interface SomeClass <protocol1, protocol2>
@end
看起來是否有點像c++中的模板類?
三,關於protocol其他的一些約定
1,protocol中的方法不需要再次在interface聲明裡面出現,因為protocol裡面已經進行了聲明,但需要在implementation中進行實現。
也就是說protocol要求實現的methods不需要再次放到header檔案的methods列表,但需要放在對應的m檔案中進行實現。
2,objective-c的介面系統有一個獨一無二的概念是如何制定一個類別,不像c/c++那樣,Printing * somevar = (Printing *) someobj,
而是可以通過id類型加上protocol的方式進行制定,如: id<Printing> somevar = someobj, 你還可以動態指定遵循多個protocol的類型,
卻從頭到尾只需用一個變數:<Printing, NSCopying> somevar = someobj;
3,就像使用@selector來測試對象的繼承關係,你可以使用@protocol來測試一個對象是否遵循某個協議,如果遵守,[someobject conformsToProtocol:@protocol(someprotocol)] 則會
返回一個YES的BOOL對象,對class也一樣:[someclass conformsToProtocol:@protocol(someprotocol)]
四,一個例子:來自《Objective-c_簡體中文手冊》
//這個是定義一個protocol的方法
1,Printing.h:
@protocol Printing
-(void) print;
@end
2,Fraction.h:
#import <Foundation/NSObject.h>
#import "Printing.h"
//可以看出protocol Printing 中的方法:print沒有出現在下面的method列表中
@interface Fraction: NSObject <Printing, NSCopying> {
int numerator;
int denominator;
}
-(Fraction*) initWithNumerator: (int) n denominator: (int) d;
-(void) setNumerator: (int) d;
-(void) setDenominator: (int) d;
-(void) setNumerator: (int) n andDenominator: (int) d;
-(int) numerator;
-(int) denominator;
@end
3,Fraction.m
#import "Fraction.h"
#import <stdio.h>
@implementation Fraction
-(Fraction*) initWithNumerator: (int) n denominator: (int) d {
self = [super init];
if ( self ) {
[ self setNumerator: n andDenominator: d];
}
return self;
}
//注意:protocol中的方法需要在這裡進行實現
-(void) print {
printf( "%i/%i", numerator, denominator );
}
-(void) setNumerator: (int) n {
numerator = n;
}
-(void) setDenominator: (int) d {
denominator = d;
}
-(void) setNumerator: (int) n andDenominator: (int) d {
numerator = n;
denominator = d;
}
-(int) denominator {
return denominator;
}
-(int) numerator {
return numerator;
}
//注意:這個是實現NSCopying protocol中的方法
-(Fraction*) copyWithZone: (NSZone*) zone {
return [[Fraction allocWithZone: zone] initWithNumerator: numerator denominator: denominator];
}
@end
4,main.m
#import <stdio.h>
#import "Fraction.h"
int main( int argc, const char *argv[] ) {
// create a new instance
Fraction *frac = [[Fraction alloc] initWithNumerator: 3 denominator: 10];
//這裡展示了如何用id加protocol的方式進行對象的引用
id <Printing> printable;
id <NSCopying, Printing> copyPrintable;
// print it
printable = frac;
printf( "The fraction is: " );
[printable print];
printf( "\n" );
// this compiles because Fraction comforms to both Printing and NSCopyable
copyPrintable = frac;
// true
if ( [frac conformsToProtocol: @protocol( NSCopying )] == YES ) {
printf( "Fraction conforms to NSCopying\n" );
}
// free memory
[frac release];
return 0;
}