3

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

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

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

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

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

4

3 回答 3

2

如果您尝试从初始化程序内部调用覆盖,它将无法正常工作。原因很容易理解:由于override属于子类,并且由于子类初始化之前需要完成超类实例初始化,调用派生方法就违反了规则" 方法被调用,实例的初始化已经完成。通常,出于同样的原因,从 Java 或 C# 构造函数调用虚拟函数并不是一个好主意。在 C++ 中,从构造函数调用 virtuals 会重定向到构造函数自己的类中的实现(即与您在 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

在日志中。

于 2012-07-13T16:39:17.647 回答
0

默认情况下,objective-c 中的所有方法都是虚拟的。所以你只需要在你的派生类中实现你想要覆盖的方法。只是不要忘记调用父方法以确保您没有错过任何内容

并确保您创建 D 类的实例,而不是 B。如果您像这样创建它

[[D alloc] init];

然后应该正确调用被覆盖的方法

于 2012-07-13T16:02:35.557 回答
0

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

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

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

于 2012-07-13T16:04:10.200 回答