1.解读一下标题
就是将同一类型不同细节的逻辑放在子类中,而基类和所有子类统称为类族。我自己理解的定义,不喜勿喷。
2.先举一个没有用类族模式的小例子。
Person类有两个类型 Teacher、Student。当吃饭的时候,显示老师在吃饭和学生在吃饭。代码如下:
@interface Person : NSObject
@property (nonatomic,copy) NSString *name;
@property (nonatomic,copy) NSString *num;
@property (nonatomic,assign) PersonType type;
+ (instancetype)personWithType:(PersonType)type;
- (void)eat;
@end
@implementation Person
+ (instancetype)personWithType:(PersonType)type{
Person * p = [[Person alloc] init];
p.type = type;
return p;
}
- (void)eat{
switch (self.type) {
case PersonTypeStudent:
NSLog(@"学生在吃饭");
break;
case PersonTypeTeacher:
NSLog(@"老师在吃饭");
break;
}
}
@end
使用情景代码
Person * p = [Person personWithType:(PersonTypeTeacher)];
[p eat]; //老师在吃饭
Person * p1 = [Person personWithType:(PersonTypeStudent)];
[p1 eat]; //学生在吃饭
这样是将所有的逻辑都写在这一个类中,当类型更多的时候,比如还有农民、医生、商人、官员等等,switch分支就会越来越多,当每种类型的逻辑再复杂点,eat方法就越来越复杂。
3.使用类族模式,Person类衍生两个子类Teacher、Student
Person基类
@interface Person : NSObject
@property (nonatomic,copy) NSString *name;
@property (nonatomic,copy) NSString *num;
@property (nonatomic,assign) PersonType type;
+ (instancetype)personWithType:(PersonType)type;
- (void)eat;
@end
@implementation Person
+ (instancetype)personWithType:(PersonType)type{
switch (type) {
case PersonTypeStudent:
return [[Student alloc] init];
break;
case PersonTypeTeacher:
return [[Teacher alloc] init];
break;
}
}
- (void)eat{
}
@end
Student类
@interface Student :Person
@end
@implementation Student
- (void)eat{
NSLog(@"学生在吃饭");
}
@end
Teacher类
@interface Teacher :Person
@end
@implementation Teacher
-(void)eat{
NSLog(@"老师在吃饭");
}
@end
使用情景代码
Person * p = [Person personWithType:(PersonTypeTeacher)];
[p eat]; //老师在吃饭
Person * p1 = [Person personWithType:(PersonTypeStudent)];
[p1 eat]; //学生在吃饭
可见使用时代码没有变,但是类中的逻辑被分割到子类中,当再加新的类型,就再增加新的子类就好了,基类基本无需改变,只需要在personWithType
方法中增加一点判断语句就行了。逻辑更加清晰。更容易维护。
其实这基本上就是工厂模式。Java中经常用这种模式再加上反射,有的时候personWithType
这类的方法都基本无需改变。
4.Cocoa中的类族
Cocoa中其实有许多类族。UIButton,还有大部分的collection类都是类族。
以NSArray为例
NSArray *array = @[@1,@2];
NSLog(@"%@",[array class]); //**__NSArrayI**
可见array的实际类型是__NSArrayl
而不是NSArray
本身。
5.判断类是否在一个类族中。
以下代码的条件将永远无法达成
if([array class] == [NSArray class]){
//不会执行
}
类族的正确判断方式
if([array isKindOfClass:[NSArray class]]){
//会执行
}
6.新增Cocoa中类似NSArray这样的子类要遵守的几点规则
- 子类应该继承自类中中的基类。
- 子类应该定义自己的数据存储方式。
- 子类应该复写超类文档中指明要复写的方法。(因为OC中没有抽象方法的概念)
网友评论