Vergil Lu
Vergil Lu

Reputation: 531

Can subclass override non-public methods

I have two classes: BatchDownloader, SpeechDownlader

BatchDownloader is the base class, and SpeechDownloader inherited it.

In BatchDownloader, whenever one file was downloaded, -(void)downloadComplete:task will be called.

But in SpeechDownloader, I also want to post a notification in downloadComplete:task.

Can I just write the method with the same name in SpeechDownloader's implementation ? or there is a better way ?

Thanks.

p.s. I don't want to make -(void)downloadComplete:task public, because it should only be called by itself.

Upvotes: 5

Views: 5274

Answers (2)

Greg
Greg

Reputation: 9168

If you implement a method in a subclass that has the same name as a private method in a superclass, your subclass method will be called on instances of your subclass.

i.e., if you implement a method in your superclass like this, without declaring it anywhere:

@implementation classA

- (void)doSomething {
    NSLog("a");
}

Then, in your subclass implementation, implement a method with the same name:

@implementation subclassOfA

- (void)doSomething {
    NSLog("b");
}

When you call doSomething on an instance of your subclass, the subclass implementation will be called instead of the superclass implementation, so the code in this example will result in "b" being printed to the console.

However, if you also want to access the superclass implementation of the method, you can use:

- (void)doSomething {
    [super doSomething];
    NSLog("b");
}

This will also call the superclass implementation. If you get a compile error (due to the method being private and super not appearing to implement it), you can use [super performSelector:@selector(doSomething)] instead to do exactly the same thing.

This happens because of the way the Objective-C runtime looks up method calls. Since these methods have exactly the same method signature (same name, return type and arguments [none]), they are considered equal, and the runtime always checks the class of the object before looking in superclasses, so it will find the subclass method implementation first.

Also, this means you can do this:

classA *test = [subclassOfA new];
[test doSomething];

And, surprise surprise, the console will print "b" (Or "a b" if you called the super implementation too).

Upvotes: 13

uchuugaka
uchuugaka

Reputation: 12782

If you implement the method with the same method signature it will be called faith your implementation, public or not.

Upvotes: 1

Related Questions