【发布时间】:2013-10-18 14:08:26
【问题描述】:
假设我有一个类 BasicDate,以及一个名为 EuroDate 的 BasicDate 的子类。类之间的区别是月-日-年与日-月-年。我知道在同一个类上使用不同的方法输出它们可能会更好......但这不是这个问题的重点。
BasicDate 有以下init method:
-(id)initWithMonth:(int)m andDay:(int)d andYear:(int)y {
if(self = [super init]) { /*initialize*/ } return self;
}
然后匹配的factory method 看起来像这样:
+(BasicDate)dateWithMonth:(int)m andDay:(int)d andYear:(int)y {
return [[BasicDate alloc] initWithMonth: m andDay: d andYear: y];
}
但如果我的子类 EuroDate 将使用 factory method 更像这样:
+(EuroDate)dateWithDay:(int)d andMonth:(int)m andYear:(int)y {
return [[EuroDate alloc] initWithDay: d andMonth: m andYear: y];
} //we can assume that EuroDate includes this init method...
这一切都很好。现在,我们假设两个类都有自己的description method,它将打印MMDDYYYY 为BasicDate,但DDMMYYYY 和EuroDate。这还是没问题的。
但如果我这样做:
EuroDate today = [EuroDate dateWithMonth:10 andDay:18 andYear:2013];
这将调用EuroDate 继承的BasicDate 工厂方法。问题是,还记得BasicDate 的工厂方法是什么样子的吗? return [[BasicDate alloc] ...]
所以today 变形为BasicDate,尽管我想将它存储为EuroDate,所以如果我调用description 方法,它将打印10182013 而不是18102013。
我找到了两个解决这个问题的方法。
解决方案1:更改BasicDate的工厂方法。而不是return [[BasicDate alloc] ...,我可以改为使用return [[[self class] alloc] ...],这可行,并且允许我将此方法用于BasicDate 或BasicDate 的任何子类,它会返回正确的对象类型。
解决方案2:Override工厂方法。我是否覆盖它以引发异常或覆盖它以执行return [[EuroDate alloc] ...]。重写它的问题是我必须重写每个子类的每个工厂方法。
哪个更好?我可能缺少的两种可能的解决方案有哪些缺点?在 Objective C 中处理这个问题的标准方法是什么?
【问题讨论】:
-
您应该查找“指定初始化程序”模式。该模式描述了如何构建子类和初始化方法以及便利构造函数(即工厂方法)。
标签: objective-c inheritance polymorphism