“类族”是一种很有用的设计模式,可以隐藏“抽象基类”背后的实现细节,使用者只需要调用基类的方法即可返回不同的子类实例。OC的系统框架中普遍使用这种模式。比如iOS的用户界面框架UIKit中就有一个名为button,NSArray等。
id maybeAnArray = /*...*/;
if ([maybeAnArray isKindOfClass:[NSArray class]]) {
//wil be hit
}
if ([maybeAnArray isMemberOfClass:[NSArray class]]) {
//wil never be hit
}
为什么会出现这种情况首先要理解两个函数
- (BOOL)isKindOfClass:(Class)aClass;
- (BOOL)isMemberOfClass:(Class)aClass;
第一个函数是接收者是否是aClass的实例或者是从这个类继承的任何类的实例,返回yes,
第二个函数是接收者是aClass的实例则返回yes。
说明maybeAnArray并不是一个NSArray类型的实例,而是其某个字类实例,其实通过不同方法实例话的array都是NSArray字类的实例,NSArray是一个抽象基类,这种设计模式就是类族模式。
书中创建类族例子:
假设有一个处理雇员的类,每个雇员都有“名字”和“薪水”这两个属性,管理者可以命令其执行日常工作。但是,各种雇员的工作内容却不同,经理在带领雇员做项目的时候,无须关心每个人如何完成其工作,仅需指示其开工即可。
定义抽象基类:
typedef NS_ENUM(NSUInteger, WKEmployeeType) {
WKEmployeeTypeDeveloper,
WKEmployeeTypeDesigner,
WKEmployeeTypeFinance,
};
@interface WKEmployee : NSObject
+ (WKEmployee *)employeeWithType:(WKEmployeeType)type;
- (void)doADayWrok;
@end
@implementation WKEmployee
+ (WKEmployee *)employeeWithType:(WKEmployeeType)type {
switch (type) {
case WKEmployeeTypeDeveloper:
return [WKEmployeeDeveloper new];
break;
case WKEmployeeTypeDesigner:
return [WKEmployeeDesigner new];
break;
case WKEmployeeTypeFinance:
return [WKEmployeeFinance new];
break;
}
}
- (void)doADayWrok {
}
@end
每个实体子类都从基类继承而来,例如:
@interface WKEmployeeDeveloper : WKEmployee
@end
@implementation WKEmployeeDeveloper
- (void)doADayWrok {
NSLog(@"%@",[[self class] description]);
}
@end
要点:
1.类族模式可以把实现细节隐藏在一套简单的公共接口后面。
2.系统框架中经常使用类族。
3.从类族的公共抽象基类中继承子类时要当心,若有开发文档,则应首先阅读。
demo:https://github.com/GitWangKai/ClassClusterDemo