類族模式在UIKit(user interface framework)使用的范圍已經(jīng)遠(yuǎn)遠(yuǎn)超過(guò)我們的想象,比如,UIButton,NSArray,NSString等,這種模式最大的好處就是,可以隱藏抽象基類背后的復(fù)雜細(xì)節(jié),使用者只需調(diào)用基類簡(jiǎn)單的方法就可以返回不同的子類實(shí)例。
首先我們先來(lái)看這兩個(gè)函數(shù):
- (BOOL)isKindOfClass:(Class)aClass;
- (BOOL)isMemberOfClass:(Class)aClass;
第一個(gè)函數(shù)的意思是:接收者是否是aClass類的實(shí)例或者從這個(gè)類繼承的任何類的實(shí)例。如果是返回yes。
第二個(gè)函數(shù)的意思是:接收者是否是aClass的實(shí)例,如果是返回yes。
按照上面的解釋我們執(zhí)行下面兩行代碼輸出結(jié)果應(yīng)該是:isKindOfClass
,isMemberOfClass
NSArray*array = [NSArray new];
if ([array isKindOfClass:[NSArray class]]) {
NSLog(@"isKindOfClass");
}
if ([array isMemberOfClass:[NSArray class]]) {
NSLog(@"isMemberOfClass");
}
但是上面代碼執(zhí)行的輸出結(jié)果卻是:isKindOfClass。
為什么會(huì)出現(xiàn)這種情況?isMemberOfClass為什么沒(méi)有執(zhí)行?array明明是NSArray的一個(gè)實(shí)例呀!難道不是嗎?為了驗(yàn)證我們的懷疑我們?cè)趫?zhí)行下面一段代碼看看array到底是什么
NSLog(@"%@",[[array class] debugDescription]);
NSLog(@"%@", [[[NSArray arrayWithObject:@"a,b"] class] debugDescription]);
輸出:__NSArray0,__NSArrayI
好吧,array果然不是NSArray的一個(gè)實(shí)例,但是上面輸出了“isKindOfClass,這說(shuō)明array是NSArray子類的一個(gè)實(shí)例,到底這種推斷正不正確?我們?cè)賮?lái)驗(yàn)證一下:
NSLog(@"%@",[[array superclass] debugDescription]);
輸出:NSArray
好吧,果然是這樣,寫(xiě)到這兒我們已經(jīng)大致明白了,通過(guò)不同方法實(shí)例化的array都是NSArray子類的實(shí)例,NSArray是一個(gè)抽象的基類。這種模式就是類族模式。
但是如果把NSArray換成UIButton又回出現(xiàn)截然相反的情況,出現(xiàn)這種情況的原因在于NSArray基類又對(duì)子類進(jìn)行了重構(gòu),生成了多個(gè)子類。
下面我們自己寫(xiě)一個(gè)類族,定義一個(gè)繼承與NSObject的抽象基類LULEmployee,基類中定義一個(gè)枚舉類型
typedef NS_ENUM(NSUInteger,LULEmployeeType) {
LULEmployeeTypeDevlopers,
LULEmployeeTypeProducters,
LULEmployeeTypeTesters,
};
為基類聲明實(shí)現(xiàn)一個(gè)類方法和實(shí)例方法
+(LULEmployee*)employeeWithType: (LULEmployeeType)type{
switch (type) {
case 0:
return [LULEmployeeTypeDevloper new];
break;
case 1:
return [LULEmployeeTypeProducter new];
break;
default:
return [LULEmployeeTypeTester new];
break;
}
}
-(void)doADayWork{
}
然后創(chuàng)建3個(gè)繼承與基類的子類,并在子類中覆寫(xiě)-(void)doADayWork方法,
Object-c demo https://github.com/luguoliang/Object-c-ClasscCluster.git
Swift demo https://github.com/luguoliang/Swift-ClasscCluster.git