1、關於分類(category):
(1)、分類用來拓展現有的類,增加方法,同時可以不必訪問主類的源代碼,也不用創建子類;
(2)、只能增加方法,不能增加變量;
(3)、在代碼中也只需要import進父類的h文件,不能編寫任何繼承的語法,因爲不是子類;
(4)、在分類裏添加的新方法會被子類繼承。
2、編寫一個分類的模板:
原類是MyClass,分類的名稱是MyClass+Cate,那麼模板如下:
#import “MyClass.h”
@interface MyClass (Cate)
… //各種方法
@end
其中要注意:import文件使用的是雙引號,@interface後面沒有繼承的冒號,緊跟着用括號聲明這個分類的名稱。可用下面的圖片來說明:
3、
分類的m文件的內容可以寫在主類的m文件裏面。
比如Class和ClassCateClass可以共用一個Class.m文件。也可以各自分開爲Class.m文件和ClassCateClass.m文件,如果分開的話, ClassCateClass.m文件應該這樣寫:
#import “ClassCateClass.h”
@implementation Class (CateClass)
…
@end
4、由3也可以看到,分類的h文件和m文件的命名方式。直接用主類名稱加上分類名稱來命名,比如Class+CateClass.h,或者可以是ClassCateClass.h;
5、擴展(extension):類的擴展是一種特殊的分類,是沒有命名的分類。擴展可以定義新的實例變量和屬性,這在分類裏是不允許的。它的定義語法和分類基本一樣,區別只是在括號裏不需要寫出名稱,保持空即可。即是只要在類名後加一對括號即可。
6、擴展類的方法是私有的,即是它定義的數據和方法只供這個類本身使用。
7、擴展類的@interface部分最好寫在主類的m文件裏,保持代碼良好的封裝性。
8、要添加額外方法,分類(category)必須在第一個@interface中聲明方法,並且在@implementation中提供實現,不然運行時會出錯。而類擴展(extension)中添加的方法可以不在第一個@interface中去聲明,而且沒有必要在擴展裏添加方法,因爲擴展裏聲明的方法是私有方法,而不需聲明只定義在@implementation中的方法就是私有方法了。
9、分類可以覆寫主類的方法,不過覆寫之後就再也不能訪問原來的方法了,因爲它們不是父類子類的關係,無法通過super關鍵字來訪問。所以如果要覆寫方法,或者使用子類,或者要先小心地把主類方法中的所有功能複製到覆寫的方法裏。
10、協議:協議是一串方法的列表,只有方法名,沒有方法的具體實現。當某些類遵守某個協議之後,在類裏面纔會去具體地定義協議包括的這些方法。當某一個類聲明遵守了某項協議之後,我們就可以在不知曉這個類的源代碼的情況下,通過協議規定的方法來訪問這個類。
11、協議使用@protocol指令和@end指令來定義,在這兩者之間僅僅需要聲明一些方法即可。聲明的方法默認是@required類型的,即是遵守這個協議的類必須去實現的。如果有一些選擇實現的方法,使用@optional去定義。模板如下,定義在h文件內:
@protocol Xprotoc
… //方法列表名,聲明在這裏的方法是遵守這個協議的類必須要實現的
@optional //從這個關鍵字開始,下方的方法列表是不強制要求實現的
… //不強制要求實現的方法列表
@required //從這個關鍵字開始,下方的方法列表又是必須要實現的了
… //要求必須實現的方法列表
@end
12、聲明某個類XCalss遵守某個協議XProtoc的模板如下:
@interface XClass: Nobject <XProtocol>
尖括號內可以列出多個協議,使用逗號分開即可。
13、如果有一個對象xClass,想要測試它是否遵循了XProtoc協議,可以使用以下方法:
if ([xClass conformsToProtocol: @protocol (XProtoc)] == YES) {
...
}
14、使用id類型聲明對象時,使用以下命令:
id <XProtoc> xClass;
那麼當程序爲xClass指定靜態類型的對象的時候,如果這個對象不遵循XProtoc協議,編譯器就會提示警告。尖括號內可以用逗號隔開多個協議,表示這個動態對象必須遵循多個協議。
15、協議也可以像類一樣進行擴展,方法即是在聲明一個新的協議的時候,使用尖括號讓它必須遵循舊的某個協議,效果其實就是舊協議的擴展。如下:
@protocol NewProtoc <XProtoc>
那麼任何採用NewProtoc協議的類都必須要同時遵循NewProtoc協議和XProtoc協議。
16、分類也可以採用某項協議,如下:
@interface XClass (CateClass) <NewProtoc>
17、如果你不想公開在h文件中聲明你的類遵循的協議,那麼你也可以把採用某些協議的語句(@interface語句,參照擴展類)寫在m文件裏,如下:
@interface XClass () < NewProtoc >
...
@end
18、定義了協議的類可以看做是把協議裏定義的方法代理(delegate)給了實現它們的類。Cocoa和iOS非常依賴代理這個概念。
19、關於合成對象:
有時子類繼承了父類之後,同時也繼承了一些子類不需要或者有衝突的方法。比如Square類繼承自Rectangle類,也繼承了Rectangle類設置長和寬的方法,但是對於Square類來說只需要設置一個邊長,繼承來的設置長和寬的方法並不適用,如果有對象不小心調用了父類繼承來的這個設置長和寬的方法,反而會出現錯誤。
那麼這時可以採取另一種處理方法:定義一個新類,然後不要讓這個新類繼承舊類,而是在這個新類中包含一個或多個它本來要繼承的舊類的對象。
這種新類的對象就是合成對象,因爲它是由其他對象組成的。比如以下的例子:
@interface Square: NSObject {
Rectangle *rect;
}
-(int) setSide: (int) s;
...
@end
注意這個Square類就不是Rectangle類的子類了,子類的對象是可以直接訪問父類的方法的,而在這個例子中,Square類的對象就沒法直接訪問Rectangle類的方法了。
這時要通過Square類的對象要訪問Rectangle類的方法就必須受到Square類的限制了,比如假設Rectangle類有一個方法-(int) area,那麼在Square類裏面可以這麼定義:
-(int) area {
return [rect area];
}
那麼要訪問Rectangle類的方法就只能通過Square類提供的area方法,實現了監控。但是要注意在合成對象的初始化的時候記得也要爲這個內部的對象rect做初始化。