java explicitly call super method - java

Are there any reason to call method from super class?
I have met lots of places where super method called instead of this method, e.g.:
public String getCustomValue() {
String value = (String) super.getValue(someArgHere);
return value;
}
Any benefits? I just see one major problem with inheritance: if I override getValue in this class or in one of its descendants getCustomValue will neglect that override and call super method.

super.getValue(someArgHere) calls the getValue method of the super class. In contrast, this.getValue(someArgHere) calls the getValue method of the current class, if defined. If the current class does not override getValue, the super class method is called.

Unless you overwrote the method getValue(...) and you are really sure (your sureness deserves a comment in the code) you want to bypass it you should not use super like you are doing. Later on if you or someone else decide to overwrite getValue(...) they probably wanted the effect to apply to getCustomValue() as well.
Although you definitely can call super.myMethodOne() from myMethodTwo(), the usual scenario is when you want to call super.myMethodOne() from myMethodOne() when you override it. Some languages like Ruby even pass up the method arguments automatically for you so that you don't have to retype them.
Here is one example:
public class A {
public void close() {
// do a bunch of things...
}
}
public class B extends A {
#Override
public void close() {
// close things related to the subclass B
// and then make sure A is closed as usual...
super.close();
}
}

There are no technical advantages of using super over this in the case where the method is not overridden.
However, one might say that it's clearer to use super instead of this for the reason you've just mentioned. If you override the function in your subclass, then you will need to use super; if you don't you can use this. Instead of playing guessing games (or forcing people to check whether the method has been overridden), you can just always use super when you mean super.

I just see one major problem with inheritance: if I override getValue in this class or in one of its descendants getCustomValue will neglect that override and call super method.
Then don't call the super method explicitly, just call getValue. If the method has not been overriden it will default to the super-method. If it has, it will use the overriden method.
I don't know if it's appropriate to ask about "benefits" in this case - it really just depends on what exactly you are trying to accomplish.

The thing is the design. When we code, we do it as per what it is!
So even if getValue is extended, its perfect, because that is what your class is suppose to do.
Normally, super is used, to obtain any information or data or side effect from the super type and modify or improve it as per your current class functionality

The only benefit is if your class overrides the method of the superclass you still can call the method of the superclass using super.

Related

Is it possible to enforce a call to a method inside of another method in Java?

I've seen that in Android, sometimes when you override a method, it always come with a call to the super class, and every once in a while, some of you can't remove this call, because the IDE show's a compile time error. So that question is, Is it possible to enforce a call to a method inside of another? And if it is, how do I do that?
Youn can use the android support annotations for this. First you need to use the support annotations in your project:
dependencies {
compile 'com.android.support:support-annotations:22.2.0'
}
Use the #CallSuper annotation.
You can write your own annotation processor for this purpose to make customs behaviors
See more:
http://tools.android.com/tech-docs/support-annotations
https://netbeans.org/kb/docs/java/annotations-custom.html
I assume you mean you get a runtime exception and a warning in your IDE. There is no way to enforce at compile time that you call super.method() when you override method.
One thing you can do is flip a boolean to true in the superclass method.
public abstract class AbstractClass {
private boolean superCalled = false;
public void foo() { superCalled = true; }
void bar() {
foo();
if (!superCalled)
throw new IllegalStateException("You did not invoke super.foo()");
}
}
Thanks to #VinceEmigh for pointing out that onCreate works in this way by setting a boolean called mCall to true. Here is the code.
This works in android because you should not call onCreate directly - it is the android system, not you, that determines when onCreate is called. The writers of the android system can just ensure that the boolean is always checked after every call.
Well, that call to super is to utilize inheritance. It lets you get away with that call so that you don't have to implement everything that the method with the same name in your super class has already implemented. Which is quite great.
About calling another method from inside a method. You are always going it in some form or the other. Functions can have helper methods; even calling a mere constructor can be called calling a method from inside a method.

Calling instance method in Java

Following this tutorial:
http://developer.android.com/training/notepad/notepad-ex2.html
In Step 2, this method gets called:
registerForContextMenu(getListView());
which is a public method of Activity. Now, I'm a bit of a Java newbie here - I thought if you wanted to call an instance method of a superclass you needed to preface it with this. E.g.
this.registerForContextMenu(getListView());
Is it just a style thing here? Is there any difference between
this.registerForContextMenu
and simply
registerForContextMenu
No, there is no difference.
You don't have to use this., but it is often done anyway to make the code clearer.
For one thing, it makes it easy to tell if a method is static or not if you use the convention of calling instance methods like this:
this.registerForContextMenu() 
and static methods like this:
ClassName.staticRegisterForContextMenu()
you do not have to use this. If you ommit it it is assumed you called method in this scope. One particular example when this may help could be i.e.:
Boolean someVar;
public function setMe( Boolean someVar ) {
this.someVar = someVar;
}
In this case, w/o this you would get the error.
To call a method of superclass either you need object of superclss or keyword super .
eg.
superObject.superclassMethod();
super.superclassMethod();
this is a reference of the current object. this can be used to call method of a class in which it is used. this can never be used to call a superclass method.
As for
this.registerForContextMenu()
and
registerForContextMenu()
no such difference. you can use either of them.
Both ways are correct for calling a method on the current (this) instance of the class. Non private methods are inherited from super classes, so you can use the same syntax to call such methods.

When NOT to call super() method when overriding?

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.)
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.
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.
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().
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..
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:
Extensibility where you want to extend what the super class can do
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.
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.
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.

Is calling static methods via an object "bad form"? Why?

In a recent question, someone asked about static methods and one of the answers stated that you generally call them with something like:
MyClassName.myStaticMethod();
The comments on that also stated that you could also call it via an object with:
MyClassName myVar;
myVar.myStaticMethod();
but that it was considered bad form.
Now it seems to me that doing this can actually make my life easier so I don't have to worry about what's static or not (a).
Is there some problem with calling static functions via an object? Obviously you wouldn't want to create a brand new object just to call it:
Integer xyzzy;
int plugh = xyzzy.parseInt ("42", 10);
But, if you already have an object of the desired type, is there a problem in using it?
(a) Obviously, I can't call a non-static method with:
MyClassName.myNonStaticMethod();
but that's not the issue I'm asking about here.
In my opinion, the real use case that makes this so unreadable is something like this. What does the code below print?
//in a main method somewhere
Super instance = new Sub();
instance.method();
//...
public class Super {
public static void method() {
System.out.println("Super");
}
}
public class Sub extends Super {
public static void method() {
System.out.println("Sub");
}
}
The answer is that it prints "Super", because static methods are not virtual. Even though instance is-a Sub, the compiler can only go on the type of the variable which is Super. However, by calling the method via instance rather than Super, you are subtly implying that it will be virtual.
In fact, a developer reading the instance.method() would have to look at the declaration of the method (its signature) to know which method it actually being called. You mention
it seems to me that doing this can actually make my life easier so I don't have to worry about what's static or not
But in the case above context is actually very important!
I can fairly confidently say it was a mistake for the language designers to allow this in the first place. Stay away.
The bad form comment comes from the Coding Conventions for Java
See http://www.oracle.com/technetwork/java/codeconventions-137265.html#587
The reason for it, if you think about it, is that the method, being static, does not belong to any particular object. Because it belongs to the class, why would you want to elevate a particular object to such a special status that it appears to own a method?
In your particular example, you can use an existing integer through which to call parseInt (that is, it is legal in Java) but that puts the reader's focus on that particular integer object. It can be confusing to readers, and therefore the guidance is to avoid this style.
Regarding this making life easier for you the programmer, turn it around and ask what makes life easier on the reader? There are two kinds of methods: instance and static. When you see a the expression C.m and you know C is a class, you know m must be a static method. When you see x.m (where x is an instance) you can't tell, but it looks like an instance method and so most everyone reserves this syntax for instance methods only.
It's a matter of communication. Calling a method on an instance implies you're acting on/with that particular instance, not on/with the instance's class.
It might get super confusing when you have an object that inherits from another object, overriding its static method. Especially if you're referring to the object as a type of its ancestor class. It wouldn't be obvious as to which method you're running.

where to call the base class's implementation in derived class?

Sometimes,deriving classes should always call through to the base implementation. where should I put the calling statement, before or after the subclass-specific code. For example:
boolean foo(T x) {
super.foo(x);
....blabla...; //< derived calss-specific code
return true;
}
OR
boolean foo(T x)
{
....blabla...; //< derived calss-specific code
return super.foo(x);
}
How to make a correct decision on different situation?
Thanks in advance.
The answer depends on what the superclass method does, and what the subclass method does.
If the work done by the superclass must be done before, put the super call before. If the work done by the superclass must be done after, put the super call after. If some work must be done before the superclass method and some after, then put it in between.
If the order doesn't matter, the usual way is to call the superclass method at the beginning.

Categories