It seems to me that when you override methods you intend to modify their usefulness.
But why evoke the same method in the superclass (in the way in which it was originally written) if it does not interest me like that? That is, modifying the method and then calling the same method on the original way it seems to me that the first change was undone by the second. Where am I wrong?
In addition to Trevor, most methods that require you calling super() means that the method you're overriding is necessary for a process lifecycle to go smoothly (as in Activities' onCreate, onPause, etc). If you fail to return super on these methods, android will complain.
On the other hand, other overridden methods that call super (you can see them when extending Android classes such as View) actually returns something (most likely a true or false) - as in some return super.methodName(args); - depending on the circumstance, you can override these to the point that you can manually return a value and skip on the super call.
You don't necessarily have to call .super() in order to invoke the method in the superclass from which your class is derived. However, very often you do so, because the stuff you're doing in your overridden method should be done in addition to the stuff performed by the superclass's method. Whether or not you do it depends on the design of the code concerned.
Some Android API methods absolutely require you to call .super() when you override them, because there's some important stuff that the superclass's method absolutely most do, even if a derived class overrides that method. If you must call .super() when overriding an Android API method, the documentation usually states so. If you fail to do so you may get an exception specifically telling you off for not doing so when you execute the code.
Related
So I've been curious about something, and it's not necessarily something I need to know, but still a curiosity.
How do you tell a inherited method that it needs to call its parent method?
An example would be say on android:
#Override
public void onResume(){
}
Method throws an error until you place super.onResume(); inside of it.
I know constructors require a super call if the parent has a required constructor, but a method call?
How do you tell your class that it can have inheritable methods, but those inherited methods need to call its parent?
Java does not have a way to require an overridden method to call up to its superclass implementation. Nor (again in contrast to constructors) can you stop it from being called more than once.
How do you tell a inherited method that it needs to call its parent
method?
There's no way for the Java compiler to enforce this, and it's likely that you wouldn't want this feature for the general case.
When a subclass overrides a superclass method, it is free to completely replace that method, if necessary, with one that is more appropriate to its own abstraction. In this case, the subclass method would never want to invoke the superclass method.
Many subclass methods supplement the existing implementation in the superclass. In this case, invoking the superclass method is natural and appropriate.
The bottom line is that the developer is free to invoke, or not invoke, based on the needs of his implementation. Would it be nice if there were a way to force the issue with some kind of method declaration that would cause the compiler to insist that the superclass method be invoked by all subclasses? Maybe...
Such details are usually implementation details and are part of the contract that should always be specified when the superclass is conceived. Such contracts (eg. such as the Object.equals() contract) are extralinguistic specifications that the compiler is not powerful enough to enforce. These contracts can and should always be specified in the superclass documentation so that all implementors know the rules of the road.
Lets think about Asynctask class.
It has overrideable methods such as onPreExecute,onProgressUpdate etc.
Compiler does not give error if i dont add super.'method-name' etc. So should i do it or not? What is the benefit of calling (or not calling) super methods when we dont have to call
When we think of extending EditText class, after your customization you need to call super constructor for sure.
NOTE: I am talking about optional super calls.
in general, and as a rule in object oriented programming: unless you have a good reason to break it, and you know exactly what's the super class method implementation all about, you should always call the super class methods.
in the specific case of AsyncTask - it is not required to call the super class method, simply because it does not doing any code.
opposite example: if you will not call the super methods of an Activity callbacks such as onCreate() and onDestroy() you will break entirely the activity, and probably nothing will work. that's because the super class implementation of this methods doing tons of stuff required from each activity.
so the conclusion is that if you are not the writer of the base class - look for documentation providing any hints about methods you which to override in order know how, and if at all you should call the super class methods.
As they are empty methods you do not have to call them. They are just there for you to use for overriding.
If you don't call the superclass's method, then...the superclass's method doesn't get called. Whether that's a problem depends entirely on what the superclass method does. If it's optional, as you say, then call it if you need to (e.g., your logic requires whatever it does) and don't call it if you don't.
If the superclass's method is empty, the only reason for coding the call to it would be if you rebased your class. E.g., suppose you had A as a base with an empty foo method, and B derived from it (class B extends A). Later, you want to be able to change it to class B extends SpecialA where SpecialA is a special version of A where foo does something. If you've left the supercall out of B's foo, you'll have to remember to add it. If you included it in the first place, you won't have to remember to add it.
(The only supercall that has to happen is a call to the superclass's constructor when constructing the object, but if you leave that out, the compiler will supply a call to the zero-args version [e.g., super()]. But that's a constructor, not a method.)
This message pertains strictly to Java. If a method is in a superclass there are two ways the method could be called:
foo();
super.foo();
Is there any harm in always doing the latter? As a coding style I prefer the latter because it's clear at a glance where the method call is coming from. Are there any circumstances where 'super' is going to be non-existent or not do what I think it would do?
I think the only harm you may have is when you want to use polymorphism so, if you call foo() and some subclass overrides foo, then the effect would be different than if you call super.foo(), basically, it depends on how you are designing the code and for what purpose.
Hope this makes it clear.
As a general rule, you should only use super.foo() inside your class foo() method. Doing otherwise, in general, goes against OOP thinking.
because it's clear at a glance where the method call is coming from
In OOP you should'n want to know where the method call "comes from". If your program (or your thinking) is depending on that, you are in potential trouble (and will probably be in actual trouble when someone decides to override the method). The method myobject.foo() must be seen from the outside as the method of the myobject's class; it should not matter if that method is implemented actually in the concrete class of its parent.
I would say there is more harm in doing the former as it's not clear that it's a method of the superclass.
Yeah this basically breaks the inheritance chain.
You don't allow the inheritance mechanism to choose what function to use even in classes derived from this one.
The point of super.foo() is to allow you to specify only when it is needed and you know no other behavior will be good.
If you do not want to explicitly avoid using an overriding method in the subclass then you should not use super.
Always using super might cause trouble if later on someone wants to override the method in the subclass.
That's a preferable way if you intend to call the method on the super class, instead of calling foo() without super.. If anyone does overwrite foo() in the subclass the super call does call the same method as before, but omiting super will now call the overwritten method. It depends on what you intent with that method call.
It depends.
If foo() is declared as final, it will make no difference at all. If foo() is not declared as final, then a subclass could override the declaration of foo() in your superclass and completely change the expected behaviour.
If you make your own class final, you can prevent it from being sub-classed, and be certain the original intent is preserved.
I would be say that this might indicate that you should think over you design again.
If you are always calling the functionality by super.foo() then you block yourself from overriding the function later, and if you don't want to have the ability to override the function, then maybe you shouldn't use inheritance as a method for accessing this functionality.
One design principle that I have heard banded about is "favour composition over inheritance", the reason for this is that your code becomes more flexible with composition rather than inheritance. And if you don't gain the positive aspects of inheritance (being able to override the function) then maybe it's wiser to not use inheritance.
Suppose that I have this method:
public void callDo(FeelFreeToExtend ext){
ext.do()
}
Where FeelFreeToExtend is this:
public class FeelFreeToExtend {
public void do(){
System.out.println("DO");
}
}
Now I know that someone could override the do method but is there a way that I can explicitly call the do method in the FeelFreeToExtend class? I don't think that this would ever be a great idea however it is still interesting.
No, it is not possible without changing the bytecode/code of all the callers. If you want to always call the FeelFreeToExtend.do() make the method final.
Append the non-access qualifier "final" to the method (make the method final), this will stop the method from being overridden and hence this version of the method will be called always from any of the subclasses.
Secondly, if you just want to access a super class method from a derived class even if the super class method has been overridden then just call the method by appending "super." before the method call.For eg. to call the method "display" of a super class from a subclass, use super.display(). (This assumes that you are the one coding the sub class)
Actually what Peter says is not completely correct: in fact it is possible to execute an overridden method using JNI (http://java.sun.com/docs/books/jni/html/fldmeth.html#26109). In JNI there are method called CallNonvirtual<Type>Method allowing exactly that.
Application servers or frameworks could be shipped with a small JNI utility to allow this kind of features...
Without JNI I don't think this is possible.
This question occured to me while programming a Android application,
but it seems to be a general programming question more.
The situation is, I am extending (subclass-ing) an class from a library, and overriding a method. how do I know if I should invoke the method of super-class? and when? (in the beginning of the overridden method or in the end?)
For example, I am overriding the method "public boolean onCreateOptionsMenu(Menu menu)" from class "Activity" in Android platform. And I saw someone write "return super.onCreateOptionsMenu(menu)" in the end of the method, in an example. But how do I know it should be done this way? and it is correct or not? what's the difference if I begin my method with "super.onCreateOptionsMenu(menu)"?
BR,
Henry
I don't think you can answer this question in the abstract: it depends on the behavior of the superclass method you're overriding.
Depending on circumstances, it may be appropriate to:
call super first
call super last
handle some cases yourself (customizations), call super for the rest
never call super
Hopefully the documentation for the particular class you're overriding will tell you if/when it's necessary to call super.
Unfortunately, there is no rule for this. You need to refer to the API docs and call super if the docs say you need to.
One hint as to whether you'll probably need to or not in Android's case is if the method you're overriding is one of the lifecycle methods. In this case, you can be fairly certain that you need to call super.
These are valid questions, but unfortunately there is no general rule to follow here.
Whether or not you need to call super method depends on the fact if the super method does something that needs to be done. In other words: are you extending or replacing the overridden method? A good API documentation of the class should give you the answer. Also, libraries often follow some conventions to make it clear how to use them.
The answer to the question where to place the super call depends on when you want to execute you’re extension. Does it need to run before or after the super method? Most often you first call super and then do something extra. But if you need to prepare something for the super method, for example modifying some object state or manipulate the arguments, you place the code before the super call. Again, the API documentation should give you the answer here.
Android will in most of the cases cause a exception if you forget to call super.
I would trust that you don't have to call super if you don't do it and it doesn't throw.
In the google groups discussions some best practices for the lifecycle methods evolved(They are not officially backed by data but used by many programmers):
If you are in a creating method like
onCreate, onResume, etc. call super
as the first statement. Thus you can be sure that everything that has to be prepared from the superclass is prepared.
If you are in a closing method like onSaveInstanceState, onPause call super last. Now you could be sure that nothing gets removed or changed to a bad state before you got everything done.
You are not required to call the super.method(), you call it only when you need it where you need it.
When you override a method in a child class then it depends on the type of the instance on which you are calling that method.
for example:
Class Animal{
public eat(){
//..
}
}
Class Dog extends Animal{
public eat(){
//..
}
}
now if you say new Dog().eat()
it executes Dog's eat method.
if you say new Animal().eat()
it executes Animal's eat method.
And you may have code like this
Animal a = new Dog();
a.eat();
which again executes the Dog's eat method as the actual instance is of the type Dog.