Boris
Boris

Reputation: 8941

Making a base class call a method in the child class

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

Answers (3)

Sergey Kalinichenko
Sergey Kalinichenko

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

Ignacio Oroná
Ignacio Oroná

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

Morion
Morion

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

Related Questions