Objective-C子类设置

时间:2014-08-25 04:02:16

标签: objective-c oop subclass init

我有3个Objective-C类:

Animal - a subclass of NSObject
Feline - a subclass of Animal
Cat - subclass of Feline

这三个类中的每一个都实现(我认为是)它自己的私有方法(-private_Setup),用于设置:

e.g。在动物:

-(instancetype)init
{
    self = [super init];
    if (self) {
        [self private_Setup];
    }
    return self;
}

在猫类和猫类中也是如此。

运行时提供了所需类的列表,因此我根据类名列表创建各种类的实例。

e.g。

NSString *className = ... // @"Animal", @"Feline" or @"Cat".
id animal = [[NSClassFromString(className) alloc] init];

问题:

如果我创建了Cat的实例,则会为继承链中的每个步骤多次调用-private_Setup。例如,Cat的调用链:

-[Cat init]
-[Feline init]
-[Animal init]
-[Cat private_Setup]    // First!

然后,来自:

-[Feline init]
-[Cat private_Setup]    // Second!

然后,来自:

-[Cat init]
-[Cat private_Setup]    // Third!

因此,我认为是每个类私有的方法,在层次结构中的每个-init之后被调用。

有人可以建议我如何解决此问题或重新设计我的设置策略?三江源。

[为了清晰起见而编辑,附加]

在继承的每个级别都需要某种形式的设置,以提供特定于该级别的数据。例如Cat特定设置。

因此,我需要的是将Cat对象完全设置为动物,猫科动物和猫。

我想一种方法是在每个级别都有不同的设置方法名称。例如setupAnimal,setupFeline,setupCat。

e.g。在动物:

-(instancetype)init
{
    self = [super init];
    if (self) {
        [self setupAnimal];
    }
    return self;
}

//在Feline中:

-(instancetype)init
{
    self = [super init];
    if (self) {
        [self setupFeline];
    }
    return self;
}

//在Cat:

-(instancetype)init
{
    self = [super init];
    if (self) {
        [self setupCat];
    }
    return self;
}

有没有比这更好,更优选的设计?

3 个答案:

答案 0 :(得分:1)

我认为您应该只在private_Setup Animal init中调用private_Setup方法。这就是全部。在所有子类中实现,在超类中只调用一次

您说您需要为每个子类设置不同的设置形式。当然!这就是为什么你要做的是在每个子类中实现[super private_Setup]。实现就像你需要为每个特定的子类。它被称为压倒一切。在重写方法内调用{{1}}。您将得到您所需要的。

答案 1 :(得分:1)

您说的是super init和超级init来电private_Setup,为什么您会感到惊讶?

我想你会感到惊讶,因为你希望链中的每个init都可以调用自己的类private_Setup。但要理解的是self的含义取决于启动链的实例的原始类(多态)。

因此,例如,如果您在初始化Cat的过程中从动物self private_Setup致电init,那么 Cat&#39> { {1}}将被调用。因此,根据您所做的安排,在Cat的初始化中,Cat private_Setup将被调用三次而其他任何一个都不会被调用。

解决方案很简单:不要使用额外的方法。初始化程序调用任何方法是一个首要的错误(而你遇到的问题是它出错的原因之一)。相反,只需在private_Setup本身中执行设置即可。这就是它的用途。

答案 2 :(得分:0)

如果我理解正确,你暗示对private_Setup的调用发生在你所有的子类中。 init方法也是如此。

从除顶部(例如Animal)init方法之外的所有方法中删除对private_Setup的调用。只要他们都拨打[super init],您就可以完全调用private_Setup。