When NOT to call super() method when overriding?

JavaAndroidOverriding

Java Problem Overview


When I make my own Android custom class, I extend its native class. Then when I want to override the base method, I always call super() method, just like I always do in onCreate, onStop, etc.

And I thought this is it, as from the very beginning Android team advised us to always call super on every method override.

But, in many books I can see that developers, more experienced than myself, often omit calling super and I really doubt they do it as a lack of knowledge. For example, look at this basic SAX parser class where super is omitted in startElement, characters and endElement:

public class SAXParser extends DefaultHandler{
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        if(qName.equalsIgnoreCase("XXY")) {
            //do something
        }
    }

    public void characters(char[] ch, int start, int length) throws SAXException {
        //do something
    }

    public void endElement(String uri, String localName, String qName) throws SAXException {
        if(qName.equalsIgnoreCase("XXY")) {
            //do something
        }else () {
            //do something
        }
    }
}

If you try to create any override method via Eclipse or any other IDE, super will always be created as a part of automated process.

This was just a simple example. Books are full of similar code.

How do they know when you must call super and when you can omit it calling?

PS. Do not bind to this specific example. It was just an example randomly picked from many examples.

(This may sound like a beginner question, but I am really confused.)

Java Solutions


Solution 1 - Java

By calling the super method, you're not overriding the behavior of the method, you're extending it.

A call to super will perform any logic the class you're extending has defined for that method. Take into account that it might be important the moment when you call super's implementation in your method overriding. For instance:

public class A { 
    public void save() { 
         // Perform save logic
    }
}

public class B extends A {
    private Object b;
    @Override
    public void save() { 
        super.save(); // Performs the save logic for A
        save(b); // Perform additional save logic
    }
}

A call to B.save() will perform the save() logic for both A and B, in this particular order. If you weren't calling super.save() inside B.save(), A.save() wouldn't be called. And if you called super.save() after save(b), A.save() would be effectively performed afterwards B.save().

If you want to override super's behavior (that is, fully ignore its implementation and provide it all yourself), you shouldn't be calling super.

In the SAXParser example you provide, the implementations of DefaultHandler for those methods are just empty, so that subclasses can override them and provide a behavior for those methods. In the javadoc for this method this is also pointed out.

public void startElement (String uri, String localName,
    String qName, Attributes attributes) throws SAXException {
    // no op
}

About the super() default call in code generated by IDEs, as @barsju pointed out in his comment, in each constructor there's an implicit call to super() (even if you don't write it in your code), which means, in that context, a call to super's default constructor. The IDE just writes it down for you, but it would also get called if you removed it. Also notice that when implementing constructors, super() or any of its variants with arguments (i.e. super(x,y,z)) can only be called at the very beginning of the method.

Solution 2 - Java

> How do they know when you must call super and when you can omit it calling?

Usually, if a special API method has a critical meaning to the underlying framework context life cycle, it will always be explicitly stated and highlighted in the API documentation, like the Activity.onCreate() API documentation. Moreover, if the API follows a robust design, it should throw some exceptions to alert the consumer developer at project compile time, and make sure it will not generate a fault at run time.

If this is not explicitly stated in the API documentation, then it is quite safe for the consumer developer to assume the API method is not mandatory to call when overriding it. It is up to the consumer developer to decide whether to use the default behavior (call the super method) or completely override it.

If the condition is permitted (I love open-source software), the consumer developer can always check out the API source code and see how the method is actually written under the hood. Check out Activity.onCreate() source and DefaultHandler.startElement() source for example.

Solution 3 - Java

The test you should do in your head is:

"Do I want all of the functionality of this method done for me, and then do something afterwards?" If yes, then you want to call super(), and then finish your method. This will be true for "important" methods such as onDraw(), which handles lots of things in the background.

If you only want some of the functionality (as with most methods that you will override) then you probably don't want to call super().

Solution 4 - Java

Well Xavi gave a better answer.. but you probably might be knowing what does super() do when called in a overridden method... it ads what have you done with the default behaviour..

e.g:

onDraw() 

method in view class when overridden.. you draw something before saying super.onDraw() it appears once the view is fully drawn.. so here calling super is necessary since android has some critically important things to do (like onCreate())

but at the same time

onLongClick()

when you override this you don't want to call super because it brings up a dialog with list of options for a EditText or any other similar view.. Thats the basic diff.. you have choice to leave it some times.. but for other methods like onCreate() , onStop() you should let the OS handle it..

Solution 5 - Java

I implemented a constraint array list like

public class ConstraintArrayList<T> extends ArrayList<T> {
  ConstraintArrayList(Constraint<T> cons) {this.cons = cons;}
  @Override
  public boolean add(T element) {
    if (cons.accept(element))
      return super.add(element);
    return false;
  }
}

If you look at the code, it simply does some pre-checking before actually letting the super class perform the actual addition of element to the list. This tells one of the two fold reasons for method overriding:

  1. Extensibility where you want to extend what the super class can do
  2. Specificity where you want to add specific behaviour through polymorphism such as in the common Animal kingdom example of move semantics where the way birds move (fly) and frogs move (hop) are specific to each sub class.

Solution 6 - Java

I didn't get your question clearly, but if you are asking about why not calling the super method:

There is a reason for calling the super method: if there is no zero argument constructor in the parent class then it is not possible to make a child class for that, so either you need to keep a no argument constructor in the parent class or you need to define super() calling statement with argument(how much argument constructor you have used in super class) at the top of the child class constructor.

I hope this helps. If not, let me know.

Solution 7 - Java

For those who also wondered which overridden methods from Android Framework should call super and found this question - here's a current hint from 2019 - Android Studio 3+ will tell you when you need it.

enter image description here

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsandaloneView Question on Stackoverflow
Solution 1 - JavaXavi LópezView Answer on Stackoverflow
Solution 2 - JavayorkwView Answer on Stackoverflow
Solution 3 - JavaMichaelView Answer on Stackoverflow
Solution 4 - JavangeshView Answer on Stackoverflow
Solution 5 - JavamaressView Answer on Stackoverflow
Solution 6 - JavaVikas GuptaView Answer on Stackoverflow
Solution 7 - JavadominikView Answer on Stackoverflow