Categoryjava
要擴展一個不可修改的類,一般的作法是爲該類建立一個子類,在子類中實現想要實現的方法,在Object-C中,能夠經過category來實現,而且實現方式更爲簡單。框架
如今有以下定義:一個包含4個方法的Fraction類ui
1 @interface Fraction : NSObject 2 @property int num, den; 3 4 -(void) setTo:(int) n over:(int) d; 5 -(void) reduce; 6 -(double) converToNum; 7 -(void) print; 8 @end
如今要爲該類增長4個方法,分別爲加法、減法、乘法和除法:spa
1 // 定義category文件:FractionMathOps.h文件 2 // 因爲category是擴展文件,全部首先須要引入原文件 3 #import "Fraction.h" 4 5 @interface Fraction (MathOps) 6 -(Fraction *) add: (Fraction *) f; 7 -(Fraction *) mul: (Fraction *) f; 8 -(Fraction *) sub: (Fraction *) f; 9 -(Fraction *) div: (Fraction *) f; 10 @end 11 12 // 可選的將implementation定義在interface文件中,或者定義在單獨的FractionMathOps.m文件中 13 @implementation Fraction (MathOps) 14 -(Fraction *) add : (Fraction *) f 15 { 16 .... 17 } 18 .... 19 @end
經過上述方法定義的category不能爲原類追加成員變量,若須要追加成員變量,在定義category時不能填寫名字,如:code
1 #import "Fraction.h" 2 3 @interface Fraction () 4 @property int uniqueID; 5 6 -(void) doStuffWithUniqueID: (int) theID; 7 @end 8 9 // ------------------------------------------------------- 10 11 // implementation實現部分,注意,Fraction後面沒有括號() 12 @implementation Fraction 13 @synthesize uniqueID; 14 15 -(void) doStuffWithUniqueID: (int) theID 16 { 17 ... 18 } 19 @end
經過這種方法爲類追加的全部方法都是private屬性的,因此只但願類本事使用這些方法,這是一個好辦法。orm
若使用category追加原類中已經方法時,原類中的方法會被覆蓋,且沒法調用原類中的方法。對象
能夠爲一個類建立多個category,若多個category文件中定義了同一個方法,Object-C沒法肯定具體會調用那個方法。blog
同時須要注意,爲一個類添加category,受影響的不單單是該類,也包括該類的子類在內。繼承
Protocols和Delegation接口
Protocol是指一系列可在多個類中共享的方法,這些方法並無特定的implementation去實現,其實就是java中的接口。
protocol中的方法有些能夠選擇性的實現,有些則必須被實現
定義protocol,只須要使用@protocol,後面接protocol的名字,以後開始像在interface中聲明方法那樣聲明protocol方法,全部方法聲明之後,以@end結尾。
在Foundation框架中,
1 @protocol NSCopying 2 - (void)copyWithZone: (NSZone *)zone; 3 @end
定義一個是否須要必須被實現的方法:@required和@optional,默認爲@required。
@protocol MyProtocol @required // 該命令能夠省略 - (void) print1; // 必須被實現 @optional - (void) print2; // 能夠不被實現 @end
一個類若要實現一個或多個protocol,只需將protocolName放到尖括號"<>"中追加到@interface後面既可,多個protocols之間使用逗號","分割。
1 @interface MyObj: NSObject <NSCopying>
在上述代碼中,因爲系統已經知道了NSCopying的定義,因此無需在interface中定義NSCopying protocol。
若一個類實現了一個或多個protocol,該類的子類一樣會實現這些protocols
可使用conformsToProtocol:方法去判斷一個對象是否實現了指定的protocol,如:
1 id currentObj; 2 ... 3 if ([currentObj conformsToProtocol: @protocol (Drawing)] == YES) 4 { 5 ... 6 }
在上述代碼中,經過使用@protocol (protocolName)的方式產生一個protocol對象
1 // 聲明一個必須實現Drawing protocol的類實例 2 // 若currentObj類中沒有實現給protocol,則編譯器會發出警告信息 3 id <Drawing> currentObj;
定義一個protocol時,能夠指定該protocol繼承另外一個protocol:
1 // MyPro1 繼承MyPro 2 // 此時實現MyPro1的類也必須實現MyPro中必需要被實現的方法 3 @protocol MyPro1 <MyPro> 4 ... 5 @end
在category中實現protocol
1 @interface MyObj (stuff) <MyPro> 2 ... 3 @end
能夠將MyPro的實現放到stuff中
1 Fraction *frac=[[Fraction alloc] initWithNumerator: 3 denominator: 5]; 2 <Printing1> p1=frac; 3 [p1 print1]; 4 id<Printing1,Printing2,Printing3> p2=frac; 5 [p2 print2]; 6 [p2 print3];