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中沒有抽象方法的概念)