gpt4 book ai didi

objective-c - 继承的工厂方法应该怎么做?

转载 作者:行者123 更新时间:2023-12-04 04:37:40 24 4
gpt4 key购买 nike

假设我有一个类(class) BasicDate ,以及 BasicDate 的子类叫 EuroDate .类之间的差异是月-日-年与日-月-年。我知道最好在同一个类上使用方法来以不同的方式输出它们......但这不是这个问题的重点。
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 ,这将打印 MMDDYYYYBasicDate ,但是 DDMMYYYYEuroDate .这一切都还好。

但如果我这样做:
EuroDate today = [EuroDate dateWithMonth:10 andDay:18 andYear:2013];

这将调用 BasicDate EuroDate 的工厂方法继承了。问题是,还记得如何 BasicDate的工厂方法看起来? return [[BasicDate alloc] ...]
所以 today多变成 BasicDate尽管我想将它存储为 EuroDate ,所以如果我调用 description方法,它会打印 10182013而不是 18102013 .

我发现这个问题有两种解决方案。

解决方案1:更改 BasicDate的工厂方法。而不是 return [[BasicDate alloc] ... ,我可以做 return [[[self class] alloc] ...]这有效,并允许我将此方法用于 BasicDateBasicDate 中的任何一个的子类,它将返回正确的对象类型。

解决方案 2: Override工厂方法。我是覆盖它以抛出异常还是覆盖它来做 return [[EuroDate alloc] ...] .覆盖它的问题是我必须覆盖每个子类的每个工厂方法。

哪个更好?我可能缺少的两种可能的解决方案有哪些缺点?在 Objective C 中处理这个问题的标准方法是什么?

最佳答案

您通常应该使用 [[[self class] alloc] init...]在工厂方法中以确保它们创建正确类的实例。请注意 class不是属性(事实上,没有“类属性”这样的东西),所以在那里使用点语法是不合适的。

编辑

正如@ArkadiuszHolko(和 Rob,谢谢)所指出的,你现在应该使用 instancetype而不是 id对于返回值,获得强类型的好处,同时保持子类的类型灵活性。顺便说一下,Apple 的命名约定建议避免​​在方法名称中使用“and”一词。因此,请考虑像这样重写您的便捷方法:

+ (instancetype)dateWithMonth:(int)month day:(int)day year:(int)year
{
return [[self alloc] initWithMonth:month day:day year:year];
}

关于objective-c - 继承的工厂方法应该怎么做?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19451744/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com