使基类调用子类中的方法

时间:2012-07-13 15:58:16

标签: objective-c inheritance

作为一名C#/ Java程序员,我很难解决以下问题:

有一个基类“B”。在其init方法中,它调用方法“SetupStuff”。 对于基类,此方法只是空的。

然后有一个继承自“B”的派生类“D”。 D也实现了“SetupStuff”方法(实际上在那里做了一些事情)。

问题是:当我创建D的对象时,永远不会调用它的“SetupStuff”。调用B的init方法,然后调用空的“SetupStuff”。

我需要做什么才能调用派生类的方法?

3 个答案:

答案 0 :(得分:2)

如果您尝试从初始化程序内部调用覆盖,则无法正常工作。它的原因很容易理解:由于覆盖属于子类,并且因为超类实例初始化需要在子类初始化开始之前完成,所以调用派生方法会违反规则,当时“常规” “方法被称为实例的初始化已经完成。通常,出于同样的原因,从Java或C#构造函数调用虚拟机并不是一个好主意。在C ++中,从构造函数中调用虚拟对象会重定向到cosntructor自己的类中的实现(即与在Objective C中观察到的相同)。

与不允许覆盖静态方法的C#和Java不同,Objective C允许您提供类方法的特定于类的实现。您可以使用此机制来实现您要执行的操作:在派生类中定义类方法,并从基类中调用它,如下所示:

@interface TT : NSObject
-(id)init;
@end

@interface Test1 : TT
+(void)doit;
@end

@interface Test2 : TT
+(void)doit;
@end

@implementation Test1
+(void) doit {
    NSLog(@"Test1");
}
@end

@implementation Test2
+(void) doit {
    NSLog(@"Test2");
}
@end

@implementation TT
-(id) init {
    if (self=[super init]) {
        // The "magic" is in the following line:
        [self->isa doit];
    }
    return self;
}
@end

致电时

[[Test1 alloc] init];
[[Test2 alloc] init];

你看

Test1
Test2

在日志中。

答案 1 :(得分:0)

objective-c中的所有方法都是默认的虚拟方法。所以你只需要在派生类中实现要覆盖的方法。只是不要忘记调用父方法来确定,你没有错过任何东西

并确保您创建D类的实例,而不是B.如果您创建它

[[D alloc] init];

然后应该正确调用重写方法

答案 2 :(得分:0)

您是否忘记使用以下命令初始化子方法:

-(void) SetupStuff{ // This is the child class implementation
[super SetupStuff];
}

在objective-c中你必须手动调用父方法,即使它们覆盖了先前存在的方法。