前言
在面試時經(jīng)常會被問到,什么是category,什么是繼承,二者有什么區(qū)別,重寫一個類是繼承好還是分類號,為什么?
比較
- Category是一種為現(xiàn)有類擴展新的方法,而不需要繼承或者改變現(xiàn)有類的方式。
- 繼承是面向?qū)ο笳Z言都有的一個特性,子類會繼承父類的方法和屬性。
如果新擴展的方法與原方法同名就不要使用category,因為系統(tǒng)有很多方法是用Category實現(xiàn)的,重寫之后,會導(dǎo)致在Runtime的時候,只有一個方法會被執(zhí)行,而哪個會被執(zhí)行是undefined。
這樣會導(dǎo)致所有引用了這個分類的方法都會遭到篡改,無法調(diào)用到原來的方法,而繼承可以使用重寫父類方法,并不會影響其他類的使用。
舉個例子吧,我們通過分類擴展UIColor。
頭文件
#import <UIKit/UIKit.h>
@interface UIColor (Extension)
+ (UIColor *)whiteColor;
+ (UIColor *)Ex_whiteColor;
@end
實現(xiàn)文件
#import "UIColor+Extension.h"
@implementation UIColor (Extension)
+ (UIColor *)whiteColor {
return [UIColor colorWithRed:0.0/255.0 green:0.0/255.0 blue: 0.0/255.0 alpha:1.0];
}
+ (UIColor *)Ex_whiteColor {
return [UIColor colorWithRed:0.0/255.0 green: 0.0/255.0 blue:0.0/255.0 alpha:1.0];
}
@end
[UIColor whiteColor];是系統(tǒng)框架UIKit提供的類方法,假設(shè)我們通過分類擴展重寫了+ (UIColor *)whiteColor;方法,而且恰好#import "UIColor+Extension.h"在預(yù)編譯時就被引用了,那么所有調(diào)用[UIColor whiteColor]設(shè)置顏色都會變成黑色而不是白色,這將會是一種災(zāi)難。
當(dāng)然我們可以通過擴展新方法+ (UIColor *)Ex_whiteColor;來達(dá)到這個目的,只要引入#import "UIColor+Extension.h",就可以調(diào)用+ (UIColor *)Ex_whiteColor;。
Category的使用場景
- 當(dāng)你在定義類的時候,在某些情況下(例如需求變更),你可能想要為其中的某個或幾個類中添加方法。
- 一個類中包含了許多不同的方法需要實現(xiàn),而這些方法需要不同團隊的成員實現(xiàn)
- 當(dāng)你在使用基礎(chǔ)類庫中的類時,你可能希望這些類實現(xiàn)一些你需要的方法。
遇到以上這些需求,Category可以幫助你解決問題。當(dāng)然,使用Category也有些問題需要注意:
- Category可以訪問原始類的實例變量,但不能添加變量,如果想添加變量,可以考慮通過繼承創(chuàng)建子類。
- Category可以重載原始類的方法,但不推薦這么做,這么做的后果是你再也不能訪問原來的方法。如果確實要重載,正確的選擇是創(chuàng)建子類。
- 和普通接口有所區(qū)別的是,在分類的實現(xiàn)文件中可以不必實現(xiàn)所有聲明的方法,只要你不去調(diào)用它。
總結(jié)
- 如果要重寫現(xiàn)有類的方法,請考慮使用繼承。
- 如果給現(xiàn)有類擴展屬性,考慮使用繼承(雖然category也可以通過runtime添加屬性,建議使用繼承)。
- 針對系統(tǒng)提供的一些類,例如:NSString,NSArray,NSNumber等類,考慮使用類別來進行方法擴展。
- 對于開發(fā)人員針對自己構(gòu)建的類,對于大型而復(fù)雜的類,建議使用類別,這有助于提高可維護性。