ind*_*roy 3 oop objective-c ios
举一个现实世界的例子,假设基类是Vehicle,具体类是TwoWheeler和FourWheeler.现在车辆的类型 - TwoWheeler或FourWheeler,由基类车辆决定.当我使用alloc-init方法创建TwoWheeler/FourWheeler的实例时,它调用下面的超级实现来设置Vehicle类中定义的公共属性的值,并且在这些属性中,其中一个是实际决定类型的类型是TwoWheeler或FourWheeler.
if (self = [super initWithDictionary:dict]){
[self setOtherAttributes:dict];
return self;
}
Run Code Online (Sandbox Code Playgroud)
现在,当我得到一些车辆时,其中一些可能是TwoWheeler而其他人则是FourWheeler.因此,我不能像这样直接创建TwoWheeler或FourWheeler的实例
Vehicle *v = [[TwoWheeler alloc] initWithDictionary:dict];
Run Code Online (Sandbox Code Playgroud)
有什么方法可以创建基类的实例,一旦我知道了类型,根据类型创建子类的实例并返回它.使用当前的实现,它将导致无限循环,因为我从具体类调用超级实现.
当我不知道事先应该实例化哪个具体类时,处理这种情况的完美设计是什么?
通常这是通过工厂完成的.
如果您希望工厂成为基类的一部分,那很好,但可能会在将来引起问题.在Objective C中,类方法构成了良好的工厂.
+ (Vehicle *)vehicleWithDictionary:(NSDictionary *)dict
{
if ([[dict objectForKey:kVehicleType] isEqualToString:@"TwoWheeler"]) {
return [[[TwoWheeler alloc] initWithDictionary:dict] autorelease];
} else if ([[dict objectForKey:kVehicleType] isEqualToString @"FourWheeler"]) {
return [[[FourWheeler alloc] initWithDictionary:dict] autorelease];
} else {
return [[[Vehicle alloc] initWithDictionary:dict] autorelease];
}
}
Run Code Online (Sandbox Code Playgroud)
工厂可以是Vehicle类的一部分,并按原样使用.
// Instead of [[Vehicle alloc] initWithDictionary:dict]
Vehicle *vehicle = [Vehicle vehicleWithDictionary:dict];
Run Code Online (Sandbox Code Playgroud)
更新
我想出了一个方法去做所要求的事情.让它成为一个光辉的例子,为什么它是一个如此糟糕的想法,为什么你永远不应该这样做.
- (id)initWithDictionary:(NSDictionary *)dict
{
self = [super init];
if (self) {
// If override is in the dictionary, then it mustn't try to call the subclass.
if (![dict objectForKey:kOverride]) {
NSMutableDictionary *overrideDict = [NSMutableDictionary dictionaryWithDictionary:dict];
[overrideDict setObject:@"override" forKey:kOverride];
if ([[dict objectForKey:kVehicleType] isEqualToString:@"TwoWheeler"]) {
[self release];
return [[[TwoWheeler alloc] initWithDictionary:overrideDict] autorelease];
} else if ([[dict objectForKey:kVehicleType] isEqualToString @"FourWheeler"]) {
[self release];
return [[[FourWheeler alloc] initWithDictionary:overrideDict] autorelease];
}
}
// init as normal
}
return self;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2372 次 |
| 最近记录: |