7

When designing a class, how do you decide when all overridden methods should call super or when none of the overridden methods should call super? Also, is it considered bad practice if your code logic requires a mixture of supered and non-supered methods like the Javascript example below?

ChildClass = new Class.create(ParentClass,
{
   /**
    * @Override
    */
   initialize: function($super) {
      $super();
      this.foo = 99;
   },

   /**
    * @Override
    */
   methodOne: function($super) {
      $super();
      this.foo++;  
   },


   /**
    * @Override
    */
   methodTwo: function($super) {
      this.foo--;  
   }
});

After delving into the iPhone and Android SDKs, I noticed that super must be called on every overridden method, or else the program will crash because something wouldn't get initialized. When deriving from a template/delegate, none of the methods are supered (obviously). So what exactly are these "je ne sais quoi" qualities that determine whether a all, none, or some overriden methods should call super?

1
  • The super must be called on every overriden method or else the program will crash (referring to iPhone and Android SDK and also in context of JavaScript) is not general object oriented design, it's technical. I override without calling 'super' just fine.
    – Joppe
    Commented Jun 24, 2011 at 23:24

2 Answers 2

12

According to Martin Fowler, this is anti-pattern.

I think it's a good read, if you don't already know that article.

Call Super is a minor smell (or anti-pattern if you like) that crops up from time to time in OO frameworks. Its symptoms are pretty easy to spot. You are inheriting from a super-class in order to plug into some framework. The documentation says something like "to do your own thing, just subclass the process method. However it's important to remember to start your method with a call to the super-class". An example might be something like this.

public class EventHandler ...
  public void handle (BankingEvent e) {
    housekeeping(e);
  }
public class TransferEventHandler extends EventHandler...
  public void handle(BankingEvent e) {
    super.handle(e);
    initiateTransfer(e);
  }

Whenever you have to remember to do something every time, that's a sign of a bad API. Instead the API should remember the housekeeping call for you. The usual way to do this is to make the handle method a Template Method, like this.

public class EventHandler ...
  public void handle (BankingEvent e) {
    housekeeping(e);
    doHandle(e);
  }
  protected void doHandle(BankingEvent e) {
  }
public class TransferEventHandler extends EventHandler ...
  protected void doHandle(BankingEvent e) {
    initiateTransfer(e);
  }

Here the super-class defines the public method and provides a separate method (often referred to as a hook method) for the subclass to override. The subclass writer now doesn't have to worry his ugly head about calls to super. Furthermore the super-class writer is free to add calls after the subclass method if she wishes...

1
  • 1
    Well, your new doHandle() is a far more restricted customization-point: You decided that omitting the call to housekeeping is not allowed, passing other argument to housekeeping is not allowed, executing other code before housekeeping is not allowed: The only thing still allowed is adding something after housekeeping. If that's the only useful thing, fine. If it isn't, you have to redesign, and things easily get really messy. Commented Dec 4, 2015 at 19:12
4

Whether or not you should call super depends on whether you are trying to add to the existing functionality of the method or to replace it. That is totally dependent on what the method is doing and in some cases may even depend on the parameters.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.