oc中經常使用分類和協議,分類和協議在專案後期可能會經常用到,尤其是為某個已經成熟的模組新增功能的時候。因為: 1
,使用分類(
category
)可以以模組的方式向類新增方法. 2
,建立標準化的方法類表供其他人實現.
下面將對分類和協議做乙個詳細介紹。
一、分類
使用場景: 1
,有時候在處理類定義時,可能想要為其新增一些新方法. 2
,假如你參與了乙個大型程式設計專案,並且作為專案的一部分,正在定義乙個新類,新類中包含許多方法.你的任務是:為該類編寫處理檔案系統的方法.其他專案成員的任務負責以下方法:建立和初始化該類例項,對該類中的物件執行操作以及在螢幕上繪製該類物件的表示. 3
,假如你已經知道如何使庫中的類(例如
fundation
的陣列類,
nsarray
),並且意識到你希望該類實現了乙個或者多個方法.當然,你可以編寫
nsarray
類的新子類並實現新方法.
針對以上所有情況的使用的解決方案可以用:分類.
分類提供了一種簡單的方式,用它可以將類的定義模組化到
相關方法的組
或者分類中.分類還提供了一種擴充套件現有類定義的簡便方式,並且不必訪問類的源**.也無需建立子類.
fraction
原始**
#import
@inte***ce fraction
:nsobject
//將例項變數轉換為屬性
@property int numerator
,denominator;
//定義例項方法 -(
void
)setto:(
int)
n over:(
int)d;
-(fraction *
)add:(
fraction *
)fraction;
-(void
)reduce;
-(double
)converttonumber;
-(void
)print;
@end;
然後,從介面部分刪除
add:方法,並將其新增到新分類,同時新增其他三種要實現的數**算.新
mathops
分類的介面部分應該如下所示.
#import "fraction.h"
#inte***ce fraction
(mathops)
-(fraction *
)add:(
fraction *)f
; -(fraction *
)mul:(
fraction *)f
; -(fraction *
)sub:(
fraction *)f
; -(fraction *
)div:(
fraction *)f
; @end;
注意:這既是介面部分的定義,也是現有介面部分的擴充套件.因此必須包括原始介面部分.這樣編譯器就知道
fraction類.
#inte***ce fraction
(mathops
):這句**告訴編譯器你正在為
fraction
編寫新的分類.而且新的分類的名稱是
mathops
.在這裡沒有列出例項變數,因為在以前定義的介面部分中已經這樣做了.實際上如果再次列出的話,將接收到編譯器發出的語法錯誤.
以上擴充套件介面的作用是:告訴編譯器,你正在
mathops
分類下為名為
fraction
類新增擴充套件.
可以將所有方法的定義放在乙個實現部分,也就是,可以在乙個實現檔案中定義
fraction.h
介面中的所有方法和
mathops
分類中的所有方法.也可以在單獨的實現部分定義分類的方法.在第二種情況下,這些方法的實現部分還必須找出方法所屬的分類.和介面部分一樣,通過將類名稱擴在類名稱之後的圓括號內類確定方法所屬的分類.
@implementation fraction
(mathops)
//code for category methods
@end;
關於分類的一些注意事項: 1
.儘管分類可以訪問原始類的例項變數,但是它不能新增自身的實力變數,如果需要新增變數,可以考慮建立子類. 2
.分類可以過載類中的另乙個方法,但是通常不這樣做,這種做法是拙劣的設計習慣.過載了乙個方法之後,再也不能訪問原來的方法. 3
.可以擁有多個分類,如果乙個方法定義在多個分類中,該語句不會執行指定使用哪個分類. 4
,和一般介面不同的是,不必實現分類中的所有方法. 5
.通過使用分類新增新方法來擴充套件不僅會影響這個類,還會影響其所有子類.
二、協議:
協議是多個類共享乙個方法列表.協議中列出的類沒有響應的實現,有其他人來實現.
協議使用指定的名稱定義一組多少有點相關的方法.這些方法通常有文件說明.所以你知道他們將如何執行.因此如果需要,可以在自己的類中定義他們的實現.
如果決定實現特定協議的所有方法,也就意味著要遵守這項協議.
定義乙個協議:下面是乙個例子
@protocol nscopying -
(id)copywithzone:(
nszone *
)zone;
@end;
如果你的類採用了
nscopy
協議,則必須遵守實現名為
copywithzone
的方法.通過在
@inte***ce
行的一對
<>
內列出協議名
可以告訴編譯器你正在使用乙個協議.這項協議的名稱放在類名和它的父類名稱之後.
如果你的類實現了多項協議,協議之間用逗號分開.
協議不引用任何型別,它是無類的.任何類都可以遵守
drawing
協議.
可以使用
conformstoprotocal
:方法檢查乙個物件是否遵守某項協議.
例如有乙個名為
currentobject
的物件,並且想要檢視它時候是遵循
drawing
協議.可以向他放鬆繪圖訊息
id currentobjec;
if([currentobjec
:conformstoprotocal
:@protoco
(drawing):
==yes])
這裡使用乙個專用的
@protocol
指令用於獲取乙個協議名稱.並產生乙個
protocol
物件.
通常在型別名稱之後的
<>
中新增協議名稱,可以借助編譯器來檢查變數的一致性.id
這告訴編譯器
currentobject
將包含遵守
drawing
協議的物件.如果這個物件遵循多個協議,可以用逗號隔開.
定義一項協議的時候,可以擴充套件現有的協議. 說明
drawwing3d
協議也使用了
drawing
協議.
最後分類也可以採用一項協議
@inte***ce fraction
(stuff)
此處fraction
類擁有乙個
stuff
分類,這個分類採用了
nscopy
,nscoding
兩個協議.
和類名稱一樣,協議名稱也是唯一的.
非正式協議:
分正式協議實際上就是乙個分類.列出了一組方法,但是並沒有實現他們.每個人都繼承相同的跟物件,因此非正式分來通常是為跟類定義的.又是非正式協議又叫做抽象協議.
宣告分正式協議的類並不自己實現這些方法,並且選擇實現這些方法的子類需要在他的介面部分重新宣告這些方法.同時還要是實現這些方法中的乙個或多個,
合成物件:
你已經學習了通過派生子類和分類技術類擴充套件類定義的集中方法.還有一項涉及定義乙個包含其他類的乙個或者多個物件的技術.
@inte***ce square
:nsobject
-(int
)setside
:(int)s
; @end
OC分類和協議
分類 分類是給原有的類擴充一系列的方法,在不改變源 的情況下給類新增 方法的簡便方法,無需建立子類。分類的一些注意事項 1,分類不能新增成員變數,自能訪問原始類的成員變數 2,分類可以重寫原類的方法,但是這樣做會導致原類的方法不能再使用 3,可以建立多個分類 4,分類宣告的方法不必全都實現 5,通過...
OC語言BLOCK和協議
oc語言 block 和協議一 bolck 一 簡介 block是什麼?蘋果推薦的型別,效率高,在執行中儲存 用來封裝和儲存 有點像函式,block 可以在任何時候執行。bolck和函式的相似性 1 可以儲存 2 有返回值 3 有形參 4 呼叫方式一樣。識別符號 二 基本使用 1 定義block變數...
OC語言BLOCK和協議
oc語言 block 和協議一 bolck 一 簡介 block是什麼?蘋果推薦的型別,效率高,在執行中儲存 用來封裝和儲存 有點像函式,block 可以在任何時候執行。bolck和函式的相似性 1 可以儲存 2 有返回值 3 有形參 4 呼叫方式一樣。識別符號 二 基本使用 1 定義block 變...