通常在Objective-C中为每个类创建一个指定的初始化程序,然后子类使用相同的初始化程序。因此,不是使用initAnimal和initDog,而是使用init。然后狗子类会定义自己的init方法,并调用指定的初始化其父类:
@implementation Dog
-(id)init
{
if((self = [super init])) { // call init in Animal and assign to self
// do something specific to a dog
}
return self;
}
@end
你真的没有指定initDog和initAnimal因为类是对的右侧声明分配...
更新:我加入了以下的答案,以反映问题的其他信息
有许多的方法,以确保子不叫比其他初始化他们指定的初始化程序和你最终的方式ely选择将主要基于您的整个设计。 Objective-C的好处之一是它非常灵活。我会在这里给你两个例子让你开始。首先,如果您创建的子类具有与其父类不同的指定初始值设定项,您可以重载父项的初始值设定项并引发异常。这会让程序员立即知道他们已经违反了班级的协议......但是,应该说你应该有一个很好的理由来做这件事,并且应该有很好的文件证明子类可能会不要使用与超类相同的初始值设定项。
@implementation Dog
-(id)init
{
// Dog does not respond to this initializer
NSAssert(false, @"Dog classes must use one of the designated initializers; see the documentation for more information.");
[self autorelease];
return nil;
}
-(id)initWithFur:(FurOptionsType)furOptions
{
if((self = [super init])) {
// do stuff and set up the fur based on the options
}
return self;
}
@end
另一种方法是让初始化器更像你的原始示例。在这种情况下,您可以更改父类的默认初始值以始终失败。然后您可以为您的父类创建一个私有初始化器,然后确保每个人都在子类中调用适当的初始化器。这种情况显然比较复杂:
@interface Animal : NSObject
-(id)initAnimal;
@end
@interface Animal()
-(id)_prvInitAnimal;
@end
@interface Dog : Animal
-(id)initDog;
@end
@implementation Animal
-(id)init
{
NSAssert(false, @"Objects must call designated initializers; see documentation for details.");
[self autorelease];
return nil;
}
-(id)initAnimal
{
NSAssert([self isMemberOfClass:[Animal class]], @"Only Animal may call initAnimal");
// core animal initialization done in private initializer
return [self _prvInitAnimal];
}
-(id)_prvInitAnimal
{
if((self = [super init])) {
// do standard animal initialization
}
return self;
}
@end
@implementation Dog
-(id)initDog
{
if((self = [super _prvInitAnimal])) {
// do some dog related stuff
}
return self;
}
@end
在这里您会看到Animal and Dog类的接口和实现。 Animal是指定的顶层对象,因此覆盖NSObject的init实现。任何在动物或动物的任何子类上调用init的人都会得到一个断言错误,将其引用到文档中。 Animal还定义了私人类别上的私人初始值设定项。私有类将留在你的代码中,当它们调用super时,Animal的子类将调用这个私有的初始化方法。它的目的是调用Animal的超类(在这种情况下为NSObject)上的init,并执行可能必需的任何通用初始化。
最后,在动物的initAnimal方法的第一行是断言,接收器实际上是一个动物,而不是一些子类。如果接收器不是动物,则程序将失败并出现断言错误,程序员将被引用到文档中。
这些只是你如何设计一些符合你的特定要求的两个例子。但是,我会强烈建议你考虑你的设计约束,看看你是否真的需要这种设计,因为它在可可和大多数OO设计框架中都是非标准的。例如,你可以考虑制作各种动物根级对象,而只需要动物协议,要求所有各种“动物”对某些动物通用消息作出响应。这样,每只动物(和动物的真正的亚类)都可以自己处理它们的指定初始化子,并且不必依赖以这种特定的非标准方式行事的超类。
好Zoul,我所做的更新基于更新你的问题我的答案......这是相当长的了,但我希望它给你一些你要找的洞察力。 – 2008-11-11 08:24:36
因为这是最好的结果。现代XCode中的答案可以通过NS_UNAVAILABLE实现。请参阅:http://stackoverflow.com/questions/195078/is-it-possible-to-make-the-init-method-private-in-objective-c#answer-27693034 – m4js7er 2016-03-17 16:20:57