作为一名C#/ Java程序员,我很难解决以下问题:
有一个基类“B”。在其init方法中,它调用方法“SetupStuff”。 对于基类,此方法只是空的。
然后有一个继承自“B”的派生类“D”。 D也实现了“SetupStuff”方法(实际上在那里做了一些事情)。
问题是:当我创建D的对象时,永远不会调用它的“SetupStuff”。调用B的init方法,然后调用空的“SetupStuff”。
我需要做什么才能调用派生类的方法?
答案 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中你必须手动调用父方法,即使它们覆盖了先前存在的方法。