Objective-c的分類和協議

梁援—晉 13年前發布 | 2K 次閱讀

在Objective-c中使用分類和協議的目的:

1,使用分類(category)以模塊的方式向類添加方法.
2,創建標準化的方法類表供其他人實現.
</div>

分類:
分類產生的背景,一下舉幾個例子
1,有時候在處理類定義時,可能想要為其添加一些新方法.(思考.在java中這種情況下是怎么做的呢?).
2,假如你參與了一個大型程序設計項目,并且作為項目的一部分,正在定義一個新類,新類中包含許多方法.你的任務是:為該類編寫處理文件系統的方法.其他項目成員的任務負責以下方法:創建和初始化該類實例,對該類中的對象執行操作以及在屏幕上繪制該類對象的表示.(思考.在java中這種情況下是怎么做的呢?).

針對以上所有情況的在Objective-C中使用的解決方案是:分類.
分類提供了一種簡單的方式,用它可以將類的定義模塊化到 相關方法的組 或者 分類中.分類還提供了一種擴展現有類定義的簡便方式,并且不必訪問類的源代碼.也無需創建子類.

例如:
Fraction原始代碼
#import <Foundation/Foundation.h>
//define the Fraction class
@interface Fraction : NSObject
{
//聲明實例變量
int numerator;
int denominator;
}
</div>
 //將實例變量轉換為屬性
@property int numerator,denominator; 
//定義實例方法
-(void) setTo: (int) n over: (int) d;
-(Fraction *) add: (Fraction *) fraction;
-(void) reduce;
-(double) convertToNumber;
-(void) print;
@end;
</div>
然后,從接口部分刪除add:方法,并將其添加到新分類,同時添加其他三種要實現的數學運算.新MathOps分類的接口部分應該如下所示.
#import "Fraction.h"
#interface Fraction (MathOps)
-(Fraction *) add: (Fraction *) f;
-(Fraction *) mul: (Fraction *) f;
-(Fraction *) sub: (Fraction *) f;
-(Fraction *) div: (Fraction *) f;
@end;
</div>
 注意:這既是接口部分的定義,也是現有接口部分的擴展.因此必須包括原始接口部分.這樣編譯器就知道Fraction類.
#interface Fraction(MathOps):這句代碼告訴編譯器你正在為Fraction編寫新的分類.而且新的分類的名稱是MathOps.在這里沒有列出實例變量,因為在以前定義的接口.以上擴展接口的作用是:告訴編譯器,你正在MathOps分類下為名為Fraction類添加擴展.
可以將所有方法的定義放在一個實現部分,也就是,可以在一個實現文件中定義Fraction.h接口中的所有方法和MathOps分類中的所有方法.也可以在單獨的實現部分定義分類的方法.在第二種情況下,這些方法的實現部分還必須找出方法所屬的分類.和接口部分一樣,通過將類名稱擴在類名稱之后的圓括號內類確定方法所屬的分類.
@implementation Fraction(MathOps)
//code for category methods
@end;
</div>

一下是關于分類需要注意的一些注意事項
1.盡管分類可以訪問原始類的實例變量,但是它不能添加自身的實力變量,如果需要添加變量,可以考慮創建子類.
2.分類可以重載類中的另一個方法,但是通常不這樣做,這種做法是拙劣的設計習慣.重載了一個方法之后,再也不能訪問原來的方法.
3.可以擁有多個分類,如果一個方法定義在多個分類中,該語句不會執行指定使用哪個分類.
4,和一般接口不同的是,不必實現分類中的所有方法.
5.通過使用分類添加新方法來擴展不僅會影響這個類,還會影響其所有子類.

協議:

協議是多個類共享一個方法列表.協議中列出的類沒有響應的實現,有其他人來實現.
協議使用指定的名稱定義一組多少有點相關的方法.這些方法通常有文檔說明.所以你知道他們將如何執行.因此如果需要,可以在自己的類中定義他們的實現.
如果決定實現特定協議的所有方法,也就意味著要遵守這項協議.
定義一個協議:下面是一個例子
@protocol NSCopying
- (id)copyWithZone: (NSZone *) zone;
@end;
</div>
如果你的類采用了NSCopy協議,則必須遵守實現名為copyWithZone的方法.通過在@interface行的一對<>內列出協議名
可以告訴編譯器你正在使用一個協議.這項協議的名稱放在類名和它的父類名稱之后.
@interface AddressBook: NSObject <NSCopy>如果你的類實現了多項協議,協議之間用逗號分開.
協議不引用任何類型,它是無類的.任何類都可以遵守Drawing協議.
</div>
可以使用ConformsToProtocal:方法檢查一個對象是否遵守某項協議.
例如有一個名為currentObject的對象,并且想要查看它時候是遵循Drawing協議.可以向他放松繪圖消息
id currentObjec;
if([currentObjec : ConformsToProtocal: @protoco (Drawing) : == YES]){
....//DO SOMETHING;
}
</div>
這里使用一個專用的@protocol指令用于獲取一個協議名稱.并產生一個Protocol對象.
通常在類型名稱之后的<>中添加協議名稱,可以借助編譯器來檢查變量的一致性.id <Drawing> currentObject;
這告訴編譯器currentObject將包含遵守Drawing協議的對象.如果這個對象遵循多個協議,可以用逗號隔開.
</div>
定義一項協議的時候,可以擴展現有的協議.
@protocol Drawwing3D <Drawing>說明Drawwing3D協議也使用了Drawing協議.
</div>
最后分類也可以采用一項協議
@interface Fraction (Stuff) <NSCopy,NSCoding>
此處Fraction類擁有一個Stuff分類,這個分類采用了NSCopy,NSCoding兩個協議.
和類名稱一樣,協議名稱也是唯一的.
 
 
非正式協議:
分正式協議實際上就是一個分類.列出了一組方法,但是并沒有實現他們.每個人都繼承相同的跟對象,因此非正式分來通常是為跟類定義的.又是非正式協議又叫做抽象協議.
 
聲明分正式協議的類并不自己實現這些方法,并且選擇實現這些方法的子類需要在他的接口部分重新聲明這些方法.同時還要是實現這些方法中的一個或多個,
 
 
 
合成對象:
你已經學習了通過派生子類和分類技術類擴展類定義的集中方法.還有一項涉及定義一個包含其他類的一個或者多個對象的技術.
@interface Square :NSObject
{
Rectangle * rect;
}
-(int) setSide:(int)s;
@end
</div>




 本文由用戶 梁援—晉 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!