Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 817
Vergil Lu Avatar asked Jun 04 '13 09:06

Vergil Lu


2 Answers

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).

like image 107
Greg Avatar answered Sep 22 '22 17:09

Greg


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

like image 31
uchuugaka Avatar answered Sep 20 '22 17:09

uchuugaka