Call subclass's method from its superclass

18,609

Solution 1

You can, as Objective C method dispatch is all dynamic. Just call it with [self methodOfChild], which will probably generate a compiler warning (which you can silence by casting self to id).

But, for the love of goodness, don't do it. Parents are supposed to provide for their children, not the children for their parents. A parent knowing about a sub-classes new methods is a huge design issue, creating a strong coupling the wrong way up the inheritance chain. If the parent needs it, why isn't it a method on the parent?

Solution 2

Technically you can do it. But I suggest you to alter your design. You can declare a protocol and make your child class adopt that protocol. Then you can have to check whether the child adopts that protocol from the super class and call the method from the super class.

Solution 3

You could use this:

Parent.m

#import "Parent.h"

@implementation Parent

- (void) methodOfChild {

    // this should be override by child classes
    NSAssert(NO, @"This is an abstract method and should be overridden");    
}

@end

The parent knows about the child and child has a choice on how to implement the function.

Solution 4

super means "invoke a method dispatching on the parent class", so can use super in the subclass because a subclass only has one parent class. A class can have many _sub_classes though, so how would you know which method implementation to call, in the general case? (Hence there is no such thing as a sub keyword.)

However, in your example you have two separate methods. There's nothing stopping you (assuming you have very good reasons for doing something like this!) from saying, in the parent,

- (void) methodOfParent {
    [self methodOfChild];
}
Share:
18,609
Confused
Author by

Confused

Updated on June 03, 2022

Comments

  • Confused
    Confused about 2 years

    I have two classes, named Parent and Child, as below. Parent is the superclass of Child I can call a method of the superclass from its subclass by using the keyword super. Is it possible to call a method of subclass from its superclass?

    Child.h

    #import <Foundation/Foundation.h>
    #import "Parent.h"
    
    @interface Child : Parent {
    
    }
    
    - (void) methodOfChild;
    
    @end
    

    Child.m

    #import "Child.h"
    
    @implementation Child
    
    - (void) methodOfChild {
    
        NSLog(@"I'm child");
    
    }
    
    @end
    

    Parent.h:

    #import <Foundation/Foundation.h>
    
    @interface Parent : NSObject {
    
    }
    
    - (void) methodOfParent;
    
    @end
    

    Parent.m:

    #import "Parent.h"
    
    @implementation Parent
    
    - (void) methodOfParent {
    
        //How to call Child's methodOfChild here?
    
    }
    
    @end
    

    Import "Parent.h" in app delegate's .m file header.

    App delegate's application:didFinishLaunchingWithOptions: method..

    Parent *parent = [ [Parent alloc] init];
    
    [parent methodOfParent];
    
    [parent release];
    
  • Tommy
    Tommy almost 13 years
    Possibly the originating poster is thinking in terms of a C++-style abstract base class (ie, one which defines methods but doesn't provide implementations), and the correct advice is to provide empty implementations on the parent, leaving a child to override them if and only if it's relevant?
  • user1025901
    user1025901 almost 13 years
    It's helpful to indicate why an answer's incorrect. As it happens, mine's not: obj-c dispatches dynamically, super means "perform the method lookup starting with my parent's method dictionary", and you might have a good reason for doing something that otherwise looks horrific.
  • Confused
    Confused almost 13 years
    Can we use protocols to do this?
  • Adam Wright
    Adam Wright almost 13 years
    You could, but you may as well add the implementation to the parent, as a protocol would declare that you have (unless it was optional, which would be a bit….weird). What situation did you want this design for? If @Tommy is right, and this is a abstract base classes code, do as he suggests and declare the method without a body, and have children override it.
  • Confused
    Confused almost 13 years
    How can we use id instead of self? Its throwing error if we use id
  • Confused
    Confused almost 13 years
    Could you please provide/share some sample code to do it with protocols?
  • Adam Wright
    Adam Wright almost 13 years
    What error? You don't "use" id, you typecast self to id to avoid the compiler potentially warning that there is no methodOfChild selector on self.
  • Confused
    Confused almost 13 years
    Can I use [self performSelector:@selector(methodOfChild)]?
  • Adam Wright
    Adam Wright almost 13 years
    Yes, but there's no benefit. You may as well just call it. Again, I would ask - why?
  • Adam Waite
    Adam Waite over 11 years
    How about this for a use case - What if you had multiple classes inheriting from the parent with each class adopting a method with the same name and didn't want to retype the calling of the method in each child (polymorph)? It can be done with delegation I suppose, but is it not just easier to use respondsToSelector?