繼承和多態(tài)
靜態(tài)工廠方法模式
#import <Foundation/Foundation.h>
// objective-c 推薦用以下方式創(chuàng)建枚舉
typedef NS_ENUM(NSUInteger, ZPEmployeeType) {
ZPEmployeeTypeManager,
ZPEmployeeTypeEngineer,
ZPEmployeeTypeSalesman
};
@interface ZPEmployee : NSObject
/**名字*/
@property (nonatomic, copy) NSString *name;
/**工資*/
@property (nonatomic, readonly) double salary;// 只讀芍殖,要寫(xiě)getter方法
/**初始化*/
// 隱藏多種員工子類型的細(xì)節(jié)只暴露員工接口給用戶調(diào)用
+ (instancetype) employeeWithType:(ZPEmployeeType) type;
@end
#import "ZPEmployee.h"
#import "ZPEngineer.h"
#import "ZPManager.h"
#import "ZPSalesman.h"
@implementation ZPEmployee
// 終極原則:高內(nèi)聚 低耦合
// 面向?qū)ο笃咴瓌t:
// 單一職責(zé)原則
// 開(kāi)閉原則
// 依賴倒轉(zhuǎn)原則
// 里氏替換原則
// 接口隔離原則
// 合成聚合復(fù)用原則
// 迪米特法則
// GoF設(shè)計(jì)模式(23種設(shè)計(jì)模式)
// 創(chuàng)建型模式:?jiǎn)卫自椤⒐S
// 結(jié)構(gòu)型模式:適配器、門(mén)面什荣、裝潢访娶、橋梁
// 行為型模式:觀察者商虐、代理
//類簇 (class cluster)
// 設(shè)計(jì)模式:靜態(tài)工廠方法模式
+ (instancetype) employeeWithType:(ZPEmployeeType) type {
ZPEmployee *employee = nil;
switch (type) {
case ZPEmployeeTypeManager:
employee = [[ZPManager alloc] init];
break;
case ZPEmployeeTypeEngineer:
employee = [[ZPEngineer alloc] init];
break;
case ZPEmployeeTypeSalesman:
employee = [ZPSalesman new];
break;
}
return employee;
}
@end
#import "ZPEmployee.h"
/**部門(mén)經(jīng)理*/
@interface ZPManager : ZPEmployee
@end
#import "ZPManager.h"
@implementation ZPManager
- (double) salary {
return 10000;
}
@end
#import "ZPEmployee.h"
/**技術(shù)工人*/
@interface ZPEngineer : ZPEmployee
/**工作時(shí)間*/
@property (nonatomic, strong) NSNumber *workingHour;
@end
#import "ZPEngineer.h"
@implementation ZPEngineer
- (double) salary {
return 200 * [_workingHour integerValue];
}
@end
#import "ZPEmployee.h"
/**銷(xiāo)售員*/
@interface ZPSalesman : ZPEmployee
/**銷(xiāo)售額*/
@property (nonatomic, strong) NSNumber *sales;
@end
#import "ZPSalesman.h"
@implementation ZPSalesman
- (double)salary {
return 1500 + 0.05 * [_sales doubleValue];
}
@end
#import <Foundation/Foundation.h>
#import "ZPManager.h"
#import "ZPSalesman.h"
#import "ZPEngineer.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSArray *empNames = @[@"馬超", @"趙云", @"典韋", @"許褚", @"陸遜", @"魏延",@"張飛"];
NSMutableArray *empsArray = [@[] mutableCopy];
for (NSString *name in empNames) {
ZPEmployee *emp = [ZPEmployee employeeWithType:arc4random() % 3];
emp.name = name;
[empsArray addObject:emp];
// ZPEmployee *emp = nil;
// int num = arc4random() % 3;
// switch (num) {
// case 0:
// emp = [ZPManager managerWithName:name];
// break;
// case 1:
// emp = [ZPEngineer engineerWithName:name];
// break;
// case 2:
// emp = [ZPSalesman salesmanWithName:name];
// break;
// }
// [empsArray addObject:emp];
}
for (ZPEmployee *emp in empsArray) {
//printf("%s", emp.name.UTF8String);
// 判斷類型
if ([emp isKindOfClass:[ZPEngineer class]]) {
printf("請(qǐng)輸入%s的本月工作時(shí)間: ", emp.name.UTF8String);
int workingHour;
scanf("%d", &workingHour);
// 通過(guò)選擇器去執(zhí)行對(duì)象方法。
[emp performSelector:@selector(setWorkingHour:) withObject:@(workingHour)];
//將父類型指針轉(zhuǎn)換成子類型指針(向下轉(zhuǎn)型崖疤,需要強(qiáng)制類型轉(zhuǎn)換)
// ZPEngineer *engineer = (ZPEngineer *)emp;
// engineer.workingHour = @(workingHour);
}
else if ([emp isKindOfClass:[ZPSalesman class]]) {
printf("請(qǐng)輸入%s的本月的銷(xiāo)售額: ", emp.name.UTF8String);
double sales;
scanf("%lf", &sales);
// id 是任意類型的指針
[emp performSelector:@selector(setSales:) withObject:@(sales)];
// ZPSalesman *salesman = (id) emp;
// salesman.sales = @(sales);
}
printf("%s本月工資為:$%.1f\n", emp.name.UTF8String, emp.salary);
}
}
return 0;
}