Soberman
Soberman

Reputation: 2596

How to forbid to inherit init method?

I have been struggling to find a correct and explicit answer, so I have decided to ask it here.

I create class A and define init method there:

@interface A : NSObject

- (id)initWithHealth:(int)hp;

@end

Then I am creating class B, that inherits from class A and define another init method there:

@interface B : A

- (id)initWithHealth:(int)hp andDamage:(int)dmg;

@end

In main, when I am going to instantiate an object from class B, I will be suggested by Xcode to use either - (id)initWithHealth:(int)hp; OR - (id)initWithHealth:(int)hp andDamage:(int)dmg; init method. How can I forbid for class B to inherit init method from class A? I want my class B to have only one init method that I define. Is there a way to achieve this?

Thanks in advance.

Upvotes: 1

Views: 135

Answers (3)

Soberman
Soberman

Reputation: 2596

EDITED (thanks to Sulthan and rmaddy)

OK I have found the answer to my question, I should have used categories. But thanks for everyone who participated.

Upvotes: 0

tjarratt
tjarratt

Reputation: 1690

In your subclass B you can explicitly define the method such that the class will not respond to it at runtime.

- (instancetype) initWithHealth:(int) hp {
    [self release];
    [super doesNotRecognizeSelector:_cmd];
    return nil;
}

This is very conventional, I've seen it used on a lot of open source projects and on some of my client's projects. I think this is preferable to @rmaddy's solution when you want to ensure the inherited method is NEVER called. If you want a sane default when the inherited init method is called, then the other code works just fine.

Upvotes: 0

rmaddy
rmaddy

Reputation: 318884

You have a few choices:

Option 1 - supply a default "damage" with the old init method. In class B you would add:

- (id)initWithHealth:(int)hp {
    return [self initWithHealth:hp andDamage:0]; // use an appropriate default
}

- (id)initWithHealth:(int)hp andDamage:(int)dmg {
    self = [super initWithHealth:hp];
    if (self) {
        // do stuff with dmg


    return self;
}

Option 2 - cause a runtime error if the old init method is used. In class B you would add:

- (id)initWithHealth:(int)hp {
    NSAssert(0, @"Dont use this");

    return nil; // make compiler happy
}

Personally I think Option 1 is the better choice.

Upvotes: 3

Related Questions