Reputation: 8941
As a C#/Java Programmer I'm having a hard time getting the following problem solved:
There is a base class "B". In its init Method it calls a method "SetupStuff". For the base class this method is just empty.
Then there is a derived class "D" that inherits from "B". D implements the method "SetupStuff", too (and actually does something there).
The problem is: When I create an object of D, its "SetupStuff" is never called. The init method of B is called, then the empty "SetupStuff" of is called.
What would I need to do to make the derived class's method being called?
Upvotes: 3
Views: 3441
Reputation: 726639
If you are trying to invoke an override from inside your initializer, it is not going to work. The reason for it is easy to understand: since the override belongs to a subclass, and because the superclass instance initialization needs to be complete before the subclass initialization can start, calling a derived method would have violated the rules that by the time a "regular" method is called the initialization of the instance has completed. Generally, calling virtuals from Java or C# constructors is not a good idea, for the same exact reason. In C++, calling virtuals from a constructor redirects to the implementation in the cosntructor's own class (i.e. the same thing that you observe in Objective C).
Unlike C# and Java where overriding static methods is not allowed, Objective C lets you provide class-specific implementations of class methods. You can use this mechanism to achieve what you are trying to do: define a class method in the derived class, and call it from the base class, like this:
@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
When you call
[[Test1 alloc] init];
[[Test2 alloc] init];
you see
Test1
Test2
in the log.
Upvotes: 2
Reputation: 4399
Did you forget to intialize the child method with:
-(void) SetupStuff{ // This is the child class implementation
[super SetupStuff];
}
in objective-c you have to call manually the parent methods, even if they are overwriting pre-existent methods.
Upvotes: 0
Reputation: 10860
all methods in objective-c are virtual by default. so you just have to implement method you want to override in your derived class. just don't forget to call parent method to be sure, that you didn' miss anything
And make sure, that you create instance of your D class, not B. If you create it like
[[D alloc] init];
then overridden method should be called properly
Upvotes: 0