Anti-pattern in object-oriented programming

Call super is a code smell or anti-pattern of some object-oriented programming languages. Call super is a design pattern in which a particular class stipulates that in a derived subclass, the user … Wikipedia
🌐
Wikipedia
en.wikipedia.org › wiki › Call_super
Call super - Wikipedia
September 2, 2025 - Call super is a code smell or anti-pattern of some object-oriented programming languages. Call super is a design pattern in which a particular class stipulates that in a derived subclass, the user is required to override a method and call back the overridden function itself at a particular point.
🌐
Quora
quora.com › Objective-C-programming-language-When-you-call-super-METHOD-are-you-calling-the-method-in-THIS-particular-instance-but-as-defined-in-the-parent-class
Objective-C (programming language): When you call [super METHOD], are you calling the method in THIS particular instance but as defined in the parent class? - Quora
Answer (1 of 4): A couple of the answers look confusing. What really happens is the message is sent to the parent version of the instance method. The runtime does a search for a matching method up the class hierarchy. The method implementation that gets called is defined inside a parent class (no...
🌐
Coderanch
coderanch.com › t › 406101 › java › Call-method-super-super-class
Call a method in super's super class?? (Beginning Java forum at Coderanch)
class C extends B { public void display() { new A().display(); // call like this System.out.println("Display of Class C called"); super.display(); // calls B's Display }} } } bye for now sat ... Class C = A + B + delta C. I wanted to call C's --> A's display. I didn't want to call display by simply create an object of A and calling the method from that newly created object within C.
Top answer
1 of 4
6

You should be able to do this:

Method method = class_getInstanceMethod([ParentParentClass class], @selector(myMethod));
IMP imp = method_getImplementation(method);
((void (*)(id, SEL))imp)(self, @selector(myMethod)); // cast the function to the correct signature

You may need to #import <objc/runtime.h> in order for this to compile.

This gets the actual C function that the method is translated to at compile time, which you can then call. When the Objective-C compiler compiles your code, all methods are translated into plain C functions, which take self as their first argument, and _cmd, the selector for the current method as the second argument, followed by all of the other arguments that the Objective-C method takes. class_getInstanceMethod obtains the runtime representation of the given method (including various metadata), and method_getImplementation gets the plain C function pointer from that method.

If you look at the Objective-C runtime header, you'll see that the IMP type is defined as typedef id (*IMP)(void);, so you need to cast it to the actual type of the method implementation function, which will be (return_type (*)(id, SEL, method_arguments_in_order)) — the function takes self and the method selector as its first two arguments, followed by the ObjC method parameters.

So, once you have the standard C function pointer, you can simply call it as you would call a function.

I wouldn't go so far as to call this approach hacky, but it certainly is non-standard, as made clear by the need to use the underlying runtime methods directly to achieve what you want. I would definitely consider this a better solution, in terms of design, reliability and making sense, than adding bridging methods in the superclass that call its superclass' methods.

2 of 4
1

super isn't an object, it's a special keyword that tells the compiler to emit calls to objc_msgSendSuper instead of objc_msgSend.

Since there is no such function as objc_msgSendSuperSuper, what you want can't be done.

You'll have to rely on a method with a different selector instead.

Top answer
1 of 3
7

You can replace the method at runtime with your own custom method like so:

#import <objc/runtime.h>

@implementation UIButton(Custom)

// At runtime this method will be called as buttonWithType:
+ (id)customButtonWithType:(UIButtonType)buttonType 
{
    // ---Add in custom code here---

    // This line at runtime does not go into an infinite loop
    // because it will call the real method instead of ours. 
    return [self customButtonWithType:buttonType];
}

// Swaps our custom implementation with the default one
// +load is called when a class is loaded into the system
+ (void) load
{
    SEL origSel = @selector(buttonWithType:);

    SEL newSel = @selector(customButtonWithType:);

    Class buttonClass = [UIButton class];

    Method origMethod = class_getInstanceMethod(buttonClass, origSel);
    Method newMethod = class_getInstanceMethod(buttonClass, newSel);
    method_exchangeImplementations(origMethod, newMethod);
}

Be careful how you use this, remember that it replaces the default implementation for every single UIButton your app uses. Also, it does override +load, so it may not work for classes that already have a +load method and rely on it.

In your case, you may well be better off just subclassing UIButton.

Edit: As Tyler notes below, because you have to use a class level method to make a button this may be the only way to override creation.

2 of 3
3

Jacob has a good point that category methods act differently than subclass methods. Apple strongly suggests that you only provide category methods that are entirely new, because there are multiple things that can go wrong otherwise - one of those being that defining a category method basically erases all other existing implementations of the same-named method.

Unfortunately for what you're trying to do, UIButton seems to be specifically designed to avoid subclassing. The only sanctioned way to get an instance of a UIButton is through the constructor [UIButton buttonWithType:]. The problem with a subclass like Jacob suggests (like this):

@implementation MyCustomButton 

+ (id)buttonWithType:(UIButtonType)buttonType {
  return [super buttonWithType:buttonType]; //super here refers to UIButton
}

@end

is that the type returned by [MyCustomButton buttonWithType:] will still be a UIButton, not MyCustomButton. Because Apple hasn't provided any UIButton init methods, there's not really a way for a subclass to instantiate itself and be properly initialized as a UIButton.

If you want some customized behavior, you can create a custom UIView subclass that always contains a button as a subview, so that you can take advantage of some of UIButton's functionality.

Something like this:

@interface MyButton : UIView {}

- (void)buttonTapped;

@end

@implementation MyButton

-(id)initWithFrame:(CGRect)frame {
  if (self = [super initWithFrame:frame]) {
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = self.bounds;
    [button addTarget:self action:@selector(buttonTapped)
     forControlEvents:UIControlEventTouchUpInside];
    [self addSubview:button];
  }
  return self;
}

- (void)buttonTapped {
  // Respond to a button tap.
}

@end

If you want the button to do different things depending on more complex user interactions, you can make more calls to [UIButton addTarget:action:forControlEvents:] for different control events.

Reference: Apple's UIButton class reference

🌐
O'Reilly
oreilly.com › library › view › c-cookbook › 0596007612 › ch08s16.html
8.15. Calling a Superclass Virtual Function - C++ Cookbook [Book]
You need to invoke a function on ... won’t give you the results you are after. Qualify the name of the member function you want to call with the target base class; for example, if you have ......
🌐
Quora
quora.com › What-is-the-purpose-of-the-super-method-in-an-object-oriented-programming-language-like-C-or-Java
What is the purpose of the super() method in an object oriented programming language like C++ or Java? - Quora
Answer (1 of 2): It represents a call to the constructor of the super class, with any arguments required - possibly none - by that constructor. The super class constructor always needs to get called once from every subclass constructor, either ...
Top answer
1 of 9
1017

I'll take the risk of stating the obvious: You call the function, if it's defined in the base class it's automatically available in the derived class (unless it's private).

If there is a function with the same signature in the derived class you can disambiguate it by adding the base class's name followed by two colons base_class::foo(...). You should note that unlike Java and C#, C++ does not have a keyword for "the base class" (super or base) since C++ supports multiple inheritance which may lead to ambiguity.

class left {
public:
    void foo();
};

class right {
public:
    void foo();
};

class bottom : public left, public right {
public:
    void foo()
    {
        //base::foo();// ambiguous
        left::foo();
        right::foo();

        // and when foo() is not called for 'this':
        bottom b;
        b.left::foo();  // calls b.foo() from 'left'
        b.right::foo();  // call b.foo() from 'right'
    }
};

Incidentally, you can't derive directly from the same class twice since there will be no way to refer to one of the base classes over the other.

class bottom : public left, public left { // Illegal
};
2 of 9
280

Given a parent class named Parent and a child class named Child, you can do something like this:

class Parent {
public:
    virtual void print(int x);
};

class Child : public Parent {
    void print(int x) override;
};

void Parent::print(int x) {
    // some default behavior
}

void Child::print(int x) {
    // use Parent's print method; implicitly passes 'this' to Parent::print
    Parent::print(x);
}

Note that Parent is the class's actual name and not a keyword.

Find elsewhere
Top answer
1 of 2
37

In your particular example, +superclass is actually the way to go:

+ (id)someClassMethod {
    return [[[self superclass] superclass] someClassMethod];
}

since it is a class method, hence self refers to the class object where +someClassMethod is being defined.

On the other hand, things get a tad more complicated in instance methods. One solution is to get a pointer to the method implementation in the supersuper (grandparent) class. For instance:

- (id)someInstanceMethod {
    Class granny = [[self superclass] superclass];
    IMP grannyImp = class_getMethodImplementation(granny, _cmd);
    return grannyImp(self, _cmd);
}

Similarly to the class method example, +superclass is sent twice to obtain the supersuperclass. IMP is a pointer to a method, and we obtain an IMP to the method whose name is the same as the current one (-someInstaceMethod) but pointing to the implementation in the supersuperclass, and then call it. Note that you’d need to tweak this in case there are method arguments and return values different from id.

2 of 2
3

Thanks to Bavarious who inspired me to involve some runtime staff.

Briefly, the desired hypothetical line:

return [super.super alloc];

can be transformed in this "real" one:

return method_getImplementation(class_getClassMethod([[self superclass] superclass], _cmd))([self class], _cmd);

To make it relatively more clear, it can be expanded as follow:

Method grannyMethod = class_getClassMethod([[self superclass] superclass], _cmd);
IMP grannyImp = method_getImplementation(grannyMethod);
return grannyImp([self class], _cmd);
🌐
QT Centre
qtcentre.org › threads › 27760-How-to-call-super-class-method-from-sub-class
How to call super class method from sub class
This has nothing to do with "different" conventions, but with basic C++. In your case, calling a mother class function (note: 'mother' here means the class from which you derived, not the a parent object) can be done by ClassName::methodName(). (as long as the method is not private) But you didn't even specify if the mother class should be an instance, or the current class just wants to access functionality in the mother class.
Top answer
1 of 2
2

First please note that this code

-(ParentClass *)field:(NSArray *)fields{
    ParentClass *pc = [[ParentClass alloc] init];
    // code      
    return pc;    
 }

Doesn't look right from the software design perspective. From what you posted it seems that ParentClass instances can create and return other instances of its own type from the field method. This doesn't look ok, but it could be fine depending on what your intentions are.

Consider making ParentClass and FieldClass different classes if that makes sense.


Regarding the subclass, the way of doing what you want would be this:

-(ParentClass *)field:(NSArray *)fields
{
   // code      
   return [super field:fields];
}

Note that I changed the returned type to be (ParentClass *), and the self to super. You cannot return a ParentClass object in the place of a SubClass object (the latter could have extra data that former doesn't know about). Doing the opposite is valid (you can return a Subclass object when someone expects to receive an object of ParentClass type).

2 of 2
1

Having said that is pretty unclear what you're trying to achieve, I'll tell what's wrong. First of all isn't enough to cast a pointer to a base class pointer, to call the superclass method, you should call it this way:

return (Subclass*) [super field:fields];  // Still wrong

But you're break polymorphism, and as the method signature says, you're returning a Subclass object, and the user that calls this method expects to have a Subclass object, but at the first call of a method that is just implemented by the subclass, it crashes because you're returning an instance of the superclass. Maybe is enough for you to change the method signature to return a ParentClass pointer, but this makes the method useless, why overriding it? It isn't pretty clear what you're trying to do, and what's your logic path.

Edit

Having seen the code that you posted on Github, here the situation is pretty different. In the Java code,t he method field returns this, so no new object gets created, and the method is just used for side effects. The add method doesn't break polymorphism, because just the object reference is of the parent class type, but if executed on a subclass it returns the object itself (this), which is of the subclass type.

In Objective-C for these cases the id type is used, which is used to represent a whatever object pointer, to a whatever class. You could also use the ParentClass type, but I'll stick to conventions. Here's an indicative code:

@implementation ParentClass

@synthesize endpoint

- (id) add: (NSString*) endpoint fields: (NSArray*) fields
{
    <code>
    return self;  
}

- (id) field: (NSArray*) fields
{
    return [self add: self.endpoint fields: fields];  
}

@end

@implementation SubClass

- (id) field: (NSArray*) fields
{
    < Additional code >
    return [self add: self.endpoint fields: fields];
}


@end
🌐
Runestone Academy
runestone.academy › ns › books › published › csawesome › Unit9-Inheritance › topic-9-4-super.html
9.4. super Keyword — CSAwesome v1
You want to still execute the superclass method, but you also want to override the method to do something else. But, since you have overridden the parent method how can you still call it? You can use super.method() to force the parent’s method to be called. We’ve used super() before to call the superclass’ constructor.
🌐
Reddit
reddit.com › r/swift › why are we allowed to not call super when overriding methods? isn't this dangerous?
r/swift on Reddit: Why are we allowed to not call super when overriding methods? Isn't this dangerous?
January 30, 2017 -

I'm currently playing around with Swift and just realized that when subclassing another class and overriding a method, I don't have to call the same method on super like you would expect. I could have sworn that other languages forced the call to super, but maybe I'm remembering incorrectly? The only methods that seem to force the call to super, at least in Swift, are initializers.

Why is not calling to super allowed when overriding inherited methods? Isn't there a huge danger here in missing out on required parent class implementation details of the method? I assumed that the compiler would immediately complain and force me to call super.

Here's a basic code example:

class AppUser {
    var name: String
    var username: String
    
    init(name: String, username: String) {
        self.name = name
        self.username = username
    }
    
    // Pretend this is actually very important and not just a print statement :)
    func importantFunctionality() {
        print("Parent class")
    }
}

class SpecialAppUser: AppUser {
    var specialId: String
    
    init(name: String, username: String, specialId: String) {
        self.specialId = specialId
        super.init(name: name, username: username)
        self.name = name
        self.username = username
    }
    
    override func importantFunctionality() {
        super.importantFunctionality() // I can comment this out or delete it with no complaints from the compiler
        print("Child class")
    }
}

let user1 = AppUser(name: "swift", username: "alwaysbeswift")
let user2 = SpecialAppUser(name: "swift", username: "alwaysbeswift", specialId: "12345")

user1.importantFunctionality()
user2.importantFunctionality()
Top answer
1 of 3
5
What if the purpose to override was to change it's functionality? without its parents implementation?
2 of 3
4
First of all, as u/sniper points out, you couldn't have true polymorphism if you always had to call super. This is a problem in a number of object-oriented languages; there's no way of specifying whether or not it's required to call super when overriding a method, much less specifying whether it should happen at the beginning or end of a method. For example, look at UIView: You're supposed to call super.viewDidLoad() at the beginning of your method if you override it, so that the superclass can set up all its view components before you make your changes. By contrast, you're supposed to call super.viewDidUnload() at the end of your method if you override it, so that you don't refer to elements in the superclass that are supposed to have been destroyed. As u/robhue points out, in Objective-C there's a macro you can use to tell the compiler that an overriding method is supposed to call the superclass's implementation. There's no equivalent that I know of in Swift, nor is there a way in either language (that I'm aware of) to say you should not call the super's implementation. One pattern you can use to force the superclass's method to be called is to have a final method that implements the functionality and separate "willX" and/or "didX" methods that subclasses can override, like so: class Foo { final func doSomethingImportant() { // Subclasses can't override this method willDoSomethingImportant() // Do some stuff... didDoSomethingImportant() } func willDoSomethingImportant() { // Subclasses can override this method to do stuff // before doSomethingImportant() is called } func didDoSomethingImportant() { // Subclasses can override this method to do stuff // after doSomethingImportant() is called } } It's not a great solution though, since it complicates the code, it means you can't actually override the superclass's behaviour, and it means you're right back to the same problem if you make subclasses of the subclass (do I need to call super.willDoSomethingImportant() in a subclass of a subclass?). It would be nice to see a way of specifying one of these behaviours in Swift, so the compiler could enforce it the same way it enforces calling super in initializer methods.
🌐
TutorialsPoint
tutorialspoint.com › how-to-call-a-parent-class-function-from-derived-class-function-in-cplusplus
How to call a parent class function from derived class function in C++?
class Derived : public Base { public: void functionName() { // Call parent class function Base::functionName(); // Derived class implementation } }; In this example, we demonstrates the method overriding in inheritance. The derived class d1 overrides the first() function of its base class p1, but also explicitly calls the base class using p1::first().
🌐
Stack Overflow
stackoverflow.com › questions › 23259746 › call-superclass-method
objective c - Call Superclass method - Stack Overflow
And I am curious what's the purpose / benefit doing so? ... Is it any design pattern? we can call directly [fooInstance fooClassMethod];. ... @Objective-J you can't.. For example I don't want to call [super someMethod].. I want to call [[fooInstance super] superMethod] to by-pass the override instead of doing [fooInstance callsuper]. Again, this is because the method is overriden.
Top answer
1 of 3
59

The usual rule of thumb is that when you are overriding a method that does some kind of initialization, you call super first and then do your stuff. And when you override some kind of teardown method, you call super last:

- (void) setupSomething {
    [super setupSomething];
    …
}

- (void) tearDownSomething {
    …
    [super tearDownSomething];
}

The first kind are methods like init…, viewWillAppear, viewDidLoad or setUp. The second are things like dealloc, viewDidUnload, viewWillDisappear or tearDown. This is no hard rule, it just follows from the things the methods do.

2 of 3
18

Just check the corresponding documentations. For instance, when to call super in overridden methods of UIViewController:

didReceiveMemoryWarning : You can override this method (as needed) to release any additional memory used by your view controller. If you do, be sure to call the super implementation at some point to allow the view controller to release its view. [Means the order is of no importance.]

loadView : Your custom implementation of this method should not call super.

setEditing:animated : This method should invoke super’s implementation before updating its view. [Means the order is of importance.]

viewWillAppear, viewDidAppear, viewWillDisappear, viewDidDisappear: If you override this method, you must call super at some point in your implementation. [Means the order is of no importance.]

dealloc: If you implement this method but are building your application for iOS 2.x, your dealloc method should release each object but should also set the reference to that object to nil before calling super. [Means the order is of importance.]

Did you realize similar rules for super in viewDidLoad and viewDidUnload methods aren't mentioned? Because you don't need to call super in these.

🌐
Fluent C++
fluentcpp.com › home › how to emulate the “super” keyword in c++
How to Emulate The "super" Keyword In C++ - Fluent C++
June 1, 2018 - A derived class sometimes needs to call the code of its base class and name it explicitly. But for bases classes with a long name, repeating it in the body of the derived class adds a lot of clutter to it. And C++ doesn’t have a super or base keyword to designate “the base class”, like C# and Java do.