1.類別(category)應用非常常見,特別是在為系統(tǒng)類進行擴展的時候,我們可以不用繼承系統(tǒng)類,直接給系統(tǒng)類添加方法。最大程度上體現(xiàn)了OC語言的動態(tài)性。但是類別只能添加方法不能添加屬性。
2.擴展(Extention)
3.繼承(inherit),一個類(子類)繼承于另一個類(父類),那么子類不僅擁有父類所有的屬性和方法,而且可以創(chuàng)建屬于自己的屬性和方法。
4.類別和繼承的使用,以下兩種情況只能使用繼承,類別無法實現(xiàn)。第一種,新擴展的方法與原方法同名,但是還需要使用父類的實現(xiàn)。因為類別會覆蓋原類的實現(xiàn),無法訪問到原來的方法。第二種,擴展類的屬性,這個類別無法做到。以下兩種情況最好使用類別,第一種,針對系統(tǒng)提供的一些類,例如:NSString,NSArray,NSNumber等類,系統(tǒng)本身不提倡使用繼承去擴展方法,因為這些類內部實現(xiàn)對繼承有所限制,所以最后使用類別來進行方法擴展。第二種,類別支持開發(fā)人員針對自己構建的類,把相關的方法分組到多個單獨的文件中,對于大型而復雜的類,這有助于提高可維護性,并簡化單個源文件的管理。
分類(Category)
分類能夠做到的事情主要是:即使在你不知道一個類的源碼情況下,向這個類添加擴展的方法。
此外,分類能夠保證你的實現(xiàn)類和其他的文件區(qū)分開。
#import “UIViewController.h”
@interface UIViewController (CustomView)
-(void)extMethod;
@end
使用分類為類添加方法(Add Methods to Classes)
通過在interface中聲明一個額外的方法并且在implementation 中定義相同名字的方法即可。分類的名字(也就是括號括起來的CustomView)表示的是:對于聲明于其他地方的這個類(UIViewController),在此處添加的方法是額外的,而不是表示這是一個新的類。你不可以通過分類為一個類添加額外的成員變量。
在implementation中,引入頭文件的時候主要引用的方式是:
#import “UIViewController+CustomView.h”
@implementation UIViewController(CustomView)
-(void)extMethod;
@end
另外,雖然Category不能夠為類添加新的成員變量,但是Category包含類的所有成員變量,即使是@private的。Category可以重新定義新方法,也可以override繼承過來的方法。
類擴展(Class Extensions)
類擴展就像匿名(也就是沒有那個括號里面的名字CustomView)的分類一樣,除了一樣不同的是,類擴展聲明必須在@implementation在實現(xiàn)。
先看一段代碼:
@interface MyObject:NSObject
{
NSNumber* number;
}
-(NSNumber*)getNum;
@end
@interface MyObject(Setter)
-(void)setNum:(NSNumber*)num;
@end
@implementation MyObject
-(NSNumber*)getNum
{
return number;
}
看上面這段代碼,有沒有問題?編譯器編譯的時候,這段代碼是可以編譯通過,但當運行時,就會報錯。為什么?
因為沒有實現(xiàn)Category中的setNum方法。而用類擴展去實現(xiàn),請看:
@interface MyObject:NSObject
{
NSNumber* number;
}
-(NSNumber*)getNum;
@end
@interface MyObject() //注意這里的括號里面是沒有名字的
-(void)setNum:(NSNumber*)num;
@end
@implementation MyObject
-(NSNumber*)getNum
{
return number;
}
-(void)setNum:(NSNumber*)num
{
number = num;
}
@end
setNum是必須要實現(xiàn),不然編譯器會提出警告。
從上面看出,分類和類擴展的相似之處是:都可以為類添加一個額外的方法;
不同之處在于:要添加額外方法,分類必須在第一個@interface中聲明方法,并且在@implementation中提供實現(xiàn),不然運行時出錯。而類擴展,你添加的方法是一個required API,如果不去實現(xiàn),編譯器會警告,而且這個方法的聲明可以不在第一個@interface中去聲明。
轉自:http://blog.csdn.net/rich_lucky/article/details/50507546
// 類別
@interface <#class name#> (<#category name#>)
@end
// 擴展
@interface <#class name#> ()
@end
// 繼承
@interface <#class name#> : <#superclass#>
@end