Why do we have to call super in Android sometimes? - java

Sometimes when I override methods, I get an exception the first time it's called like below:
05-31 21:32:04.266: E/AndroidRuntime(28471): android.support.v4.app.SuperNotCalledException:
Fragment AnalFragment{41795860 #1 id=0x7f070002} did not call through to super.onDestroy()
Why are we forced to call super.method()? It makes sense that there are obligations by the parent class, but more importantly, how do we know that a method requires super to be called, rather than waiting for it to crash?

Why are we forced to call super.method()?
The classes that make up the Android SDK can be incredibly complex. For instance, both activities and fragments must perform a number of operations in order to function properly (i.e. managing life cycle, optimizing memory usage, drawing the layout to the screen, etc.). Requiring the client to make a call to the base class (often at the beginning of the method) ensures that these operations are still performed, while still providing a reasonable level of abstraction for the developer.
How do we know that a function method requires super to be called?
The documentation should tell you whether or not this is required. If it doesn't I'd Google-search for some sample code (or check the API demos... or better yet, look at the source code!). It shouldn't be too difficult to figure out.

I know this is not the true intention of the OP, he did ask this question and I don't believe it got a very good answer so, if anybody is ever wondering "Why the heck do I HAVE to call super?!? If they're going to require it, why don't they just do it for me!!!". Here's the answer to that questions....
Basically, super() is something that must be called if you're overriding something that MUST be called, which can often be rather complicated code. Now, the reason they don't just do it for you and call it before your function is mostly so that you have control! :-D
To be more specific, you cannot control IF you call super(), however, you can control WHEN!
So, let's say you have some specific code that needs to happen BEFORE super() gets called, you now have the freedom to call super() only after running your code. Or... let's say you require super() to have already ran for your code not to crash, you now have the option to run super() before running your code, hence ensuring that everything is set up for you. Heck, you could even technically override the superclass hardcore and code your own method that takes care of super() itself, and make it so you don't have to call super(), but 99.9% of the time sane people will not need to do this! :-P
So, the short answer to "why do I have to call super()" is... So that you can control when it's called and do things before, or after super() gets ran. :-)

The super keyword has two main uses
1. Calls the superclass’ constructor.
2. Access a member of the superclass that has been hidden by a member of a subclass.
So, why need to user super keyword sometimes ? Answer would be android comes under 4GL language which means it has many functionality ready made. While we are overridding these methods for the customization we use super keyword.
see the very simple usage of super keyword in android ( as we do it most of the time ).
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
.
.
.
}
super() must always be the first statement executed inside a subclass’ constructor. When a subclass calls super(), it is calling the constructor of its immediate superclass. The second form of super is most applicable to situations in which member names of a subclass hide members by the same name in the superclass.

The requirement is generally specified directly in the API documentation. For example, see android.widget.ListView.onFinishInflate:
protected void onFinishInflate ()
...
Even if the subclass overrides onFinishInflate, they should always be sure to call the super method, so that we get called.
Unfortunately, my personal experience is that Android docs are uneven in quality. So, I suspect there are cases where the call is required but not documented as such.

It is important to note that once you override a method, you basically ignore everything that was in the parent class and instead have your own custom implementation in the child class (literally overwriting it)!
In our case, we don't want to throw away the parent implementation. We actually want to continue to use the original method, and ADD the extra checks for each child class individually.
This is where we get to use the "super" keyword!
You are allowed to re-use the parent method in the child class by using the "super" keyword, followed by a dot and then the method name:
for example: isValidMove(position) is method for chess pieces & check move validity & bound in the 8x8 chess board.
super.isValidMove(position);
Using the keyword super here means that we want to run the actual method in the super (or parent) class from inside the implementation in "this" class.
Which means in each of the child classes, before you get to check the custom movement, you can check if super.isValidMove(position) has returned false. If so, then no need to do any more checks and immediately return false; otherwise, continue checking.
The new implementation for the Rook class will look like this:
class Rook extends Piece{
boolean isValidMove(Position newPosition){
// First call the parent's method to check for the board bounds
if(!super.isValidMove(position)){
return false;
}
// If we passed the first test then check for the specific rock movement
if(newPosition.column == this.column && newPosition.row == this.row){
return true;
}
else{
return false;
}
}
}
You can also use super() to call the parent's constructor. This is usually done when implementing the child's constructor. Typically you would want to first run everything in the parent's constructor then add more code in the child's constructor:
class Rook extends Piece{
// default constructor
public Rook(){
super(); // this will call the parent's constructor
this.name = "rook";
}
}
Note: If a child's constructor does not explicitly call the parent's constructor using super, the Java compiler automatically inserts a call to the default constructor of the parent class. If the parent class does not have a default constructor, you will get a compile-time error.

As a basic, super is a method used to refer the main superclass field/method from which class extension is done(using extends in the initial class definition) or whose instance is created from.
When we need a most basic definition to be altered of the method/field of the superclass to be used to solve our purpose.
for example
java.lang.Object (has a lot of methods & fields) >android.view.View >android.view.ViewGroup >android.widget.LinearLayout
But if you need to change/use as it is a method of the Object Class then you need the Super method to refer the first time created method in the object class within
the LinearLayout class.

Related

Which overridden methods should have a call to super and where? [duplicate]

Sometimes when I override methods, I get an exception the first time it's called like below:
05-31 21:32:04.266: E/AndroidRuntime(28471): android.support.v4.app.SuperNotCalledException:
Fragment AnalFragment{41795860 #1 id=0x7f070002} did not call through to super.onDestroy()
Why are we forced to call super.method()? It makes sense that there are obligations by the parent class, but more importantly, how do we know that a method requires super to be called, rather than waiting for it to crash?
Why are we forced to call super.method()?
The classes that make up the Android SDK can be incredibly complex. For instance, both activities and fragments must perform a number of operations in order to function properly (i.e. managing life cycle, optimizing memory usage, drawing the layout to the screen, etc.). Requiring the client to make a call to the base class (often at the beginning of the method) ensures that these operations are still performed, while still providing a reasonable level of abstraction for the developer.
How do we know that a function method requires super to be called?
The documentation should tell you whether or not this is required. If it doesn't I'd Google-search for some sample code (or check the API demos... or better yet, look at the source code!). It shouldn't be too difficult to figure out.
I know this is not the true intention of the OP, he did ask this question and I don't believe it got a very good answer so, if anybody is ever wondering "Why the heck do I HAVE to call super?!? If they're going to require it, why don't they just do it for me!!!". Here's the answer to that questions....
Basically, super() is something that must be called if you're overriding something that MUST be called, which can often be rather complicated code. Now, the reason they don't just do it for you and call it before your function is mostly so that you have control! :-D
To be more specific, you cannot control IF you call super(), however, you can control WHEN!
So, let's say you have some specific code that needs to happen BEFORE super() gets called, you now have the freedom to call super() only after running your code. Or... let's say you require super() to have already ran for your code not to crash, you now have the option to run super() before running your code, hence ensuring that everything is set up for you. Heck, you could even technically override the superclass hardcore and code your own method that takes care of super() itself, and make it so you don't have to call super(), but 99.9% of the time sane people will not need to do this! :-P
So, the short answer to "why do I have to call super()" is... So that you can control when it's called and do things before, or after super() gets ran. :-)
The super keyword has two main uses
1. Calls the superclass’ constructor.
2. Access a member of the superclass that has been hidden by a member of a subclass.
So, why need to user super keyword sometimes ? Answer would be android comes under 4GL language which means it has many functionality ready made. While we are overridding these methods for the customization we use super keyword.
see the very simple usage of super keyword in android ( as we do it most of the time ).
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
.
.
.
}
super() must always be the first statement executed inside a subclass’ constructor. When a subclass calls super(), it is calling the constructor of its immediate superclass. The second form of super is most applicable to situations in which member names of a subclass hide members by the same name in the superclass.
The requirement is generally specified directly in the API documentation. For example, see android.widget.ListView.onFinishInflate:
protected void onFinishInflate ()
...
Even if the subclass overrides onFinishInflate, they should always be sure to call the super method, so that we get called.
Unfortunately, my personal experience is that Android docs are uneven in quality. So, I suspect there are cases where the call is required but not documented as such.
It is important to note that once you override a method, you basically ignore everything that was in the parent class and instead have your own custom implementation in the child class (literally overwriting it)!
In our case, we don't want to throw away the parent implementation. We actually want to continue to use the original method, and ADD the extra checks for each child class individually.
This is where we get to use the "super" keyword!
You are allowed to re-use the parent method in the child class by using the "super" keyword, followed by a dot and then the method name:
for example: isValidMove(position) is method for chess pieces & check move validity & bound in the 8x8 chess board.
super.isValidMove(position);
Using the keyword super here means that we want to run the actual method in the super (or parent) class from inside the implementation in "this" class.
Which means in each of the child classes, before you get to check the custom movement, you can check if super.isValidMove(position) has returned false. If so, then no need to do any more checks and immediately return false; otherwise, continue checking.
The new implementation for the Rook class will look like this:
class Rook extends Piece{
boolean isValidMove(Position newPosition){
// First call the parent's method to check for the board bounds
if(!super.isValidMove(position)){
return false;
}
// If we passed the first test then check for the specific rock movement
if(newPosition.column == this.column && newPosition.row == this.row){
return true;
}
else{
return false;
}
}
}
You can also use super() to call the parent's constructor. This is usually done when implementing the child's constructor. Typically you would want to first run everything in the parent's constructor then add more code in the child's constructor:
class Rook extends Piece{
// default constructor
public Rook(){
super(); // this will call the parent's constructor
this.name = "rook";
}
}
Note: If a child's constructor does not explicitly call the parent's constructor using super, the Java compiler automatically inserts a call to the default constructor of the parent class. If the parent class does not have a default constructor, you will get a compile-time error.
As a basic, super is a method used to refer the main superclass field/method from which class extension is done(using extends in the initial class definition) or whose instance is created from.
When we need a most basic definition to be altered of the method/field of the superclass to be used to solve our purpose.
for example
java.lang.Object (has a lot of methods & fields) >android.view.View >android.view.ViewGroup >android.widget.LinearLayout
But if you need to change/use as it is a method of the Object Class then you need the Super method to refer the first time created method in the object class within
the LinearLayout class.

Why does a sub-class call super() by default?

This question has been bugging me for a while now, and I haven't found a good answer (other than "that's just how it is").
Let me give some background code, to show what I'm talking about.
class Note {
private final String name = "Note";
public Note() {
System.out.println(name);
}
// ...
}
class Todo extends Note {
private final String name = "Todo";
public Todo() {
System.out.println(name);
}
// ...
}
// ...
Note note = new Todo(); // case 1
Todo todo = new Todo(); // case 2
So how come both case 1 and case 2 print out:
Note
Todo
This makes no sense, since Todo() (constructor) does not call super() (at least not visibly). Why would the sub-class have to call the parents default constructor, why not just require any sub-class to implement a constructor?
I read a couple questions related to this, but none answer why.
Edit:
I guess my example was kind of poor, but It's actually a derivative from a Java 7 Certification question.. From the collective of answers I now understand why. Let me provide a better example:
public Note {
private String description;
public Note() {
description = "I'm a Note";
}
public Note( String description ) {
this.description = description;
}
// getters/setters/etc.
}
public Todo extends Note {
// field vars..
public Todo() {
// empty constructor
}
// getters/setters/etc..
}
So now this makes more sense, since when Todo is created, if super() was not inserted behind the covers, the Note aspect of the Todo would not be initialized. Which would be pointless to have a sub-class in that case. Thanks all!
The subclass constructor has to call some constructor. If you haven't told it which to use, it will use the default constructor.
The alternative is having variables in the superclass be completely uninitialized and yet accessible by the subclass and/or its methods, which would be spectacularly bad.
The decision to silently call the default superclass constructor, rather than e.g. fail to compile, is debatable, though, but I suspect it's tied to the existence of a "default constructor" in the first place.
FYI, your question also suggests that you might be getting confused about inheritance. The Note.name and the Todo.name fields are completely separate: you cannot override a field in a subclass, only methods.
The question can be separated into two parts.
Why does any constructor of the superclass have to be called? This is easy: the constructor is responsible for setting up the state of the object, and since there can be state in the superclass not visible to the subclass code (i.e. private fields), this can only be dealt with by calling a constructor of the superclass.
Why don't you have to call super() explicitly? This is just a fairly arbitrary design decision made in Java to make code look simpler. It ties in nicely with the concept of a default constructor (i.e. the implied no-arg constructor that exists in classes that don't have an explicit constructor defined), although as can be seen in your example, it also works when you have a no-arg constructor explicitly defined in the superclass.
You don't have to call a superclass constructor explicitly. And it is not necessary to have a super() or super(arguments) call in a subclass constructor. If you do not specify that, the compiler will automatically add a call to the no-arguments superclass constructor.
If the superclass does not have a no-arguments constructor, then you must explicitly call super(arguments) in each subclass constructor.
The reason why both case print out Note and Todo is that you create using operator new always instance of class Todo. If you have wrote
Note note = new Note();
Note todo = new Todo();
Then result would be:
Note
Note
Todo
The cause of that behavior is Polymorphism.
To answer why constructor must call super constructor to create itself is easy to picture. As it use the elements of that super class that class must be created first, so the class that inherit it can operate on it.
In your example, the parent's constructor doesn't do anything with the object.
Generally, a constructor does some construction of the object by setting fields. These fields are known to the constructor of the that class and might not be settable or accessible in another class and you would wouldn't want to duplicate all that code in every sub-class (that is already in the parent class) just so the parent fields are set correctly.
So it makes sense for each class to initialise the fields it knows about and not depend on the behaviour of sub-class to much to behave correctly. This allows you to change one class without having to change it's sub classes. e.g. adding or changing a field.
In fact, it does. The super() call is automatically added even if you don't write it. It is the first instruction in Todo's constructor.
To test this yourself, just create a new Note constructor with a parameter and delete the empty one. See what happens now:)
Why does this happens? Well, it's simple: because this is how it's implemented.
The documentation says it all:
If a constructor does not explicitly invoke a superclass constructor,
the Java compiler automatically inserts a call to the no-argument
constructor of the superclass. If the super class does not have a
no-argument constructor, you will get a compile-time error. Object
does have such a constructor, so if Object is the only superclass,
there is no problem.
That's just how it is! :)
To me it all make sense because the main reason you write your code in Object Oriented Programming paradigm is to reuse existing code.
There are many ways you can reuse, one of them is to inherit a class (ie: creating a subclass).
When you inherit a class, then you also inherit how that class is created.
In my opinion Java will be a much more confusing language if such behavior doesn't exist

Calling superclass constructor with super or just setTitle?

What is the recommended method of setting the title with setTitle("Title")or super("Title") while extending javax.swing.JFrame in terms of performance?
If you grepcode JFrame (in OpenJDK 6-b14), and dig a bit, you see that the constructor JFrame() calls the constructor Frame(), which calls Frame("") (link).
So, since an implicit super() is added if you don't specify a call to any super constructor yourself, it would be (although very slightly so) more effective to call super("Title").
If you're in your constructor, try to delegate as much functionality as possible to the super constructor. It's possible that you can save it from doing some work.
For instance, the default super constructor might create some inner objects that will just get overwritten when you call the setter. If you pass the correct data immediately, you give it the opportunity to be more efficient.
But I think in this specific case, it does not matter much.
It is a good practice to always call the corresponding super(.....) when you extend a class.
As you never know what magic the super constructor does behind the scene.
You never need just
call super();
That's what will be there if you don't specify anything else. You only need to specify the constructor to call if:
You want to call a superclass constructor which has parameters
You want to chain to another constructor in the same class instead of the superclass constructor

Virtual Functions during Construction. Why Java is different than C++

I had a test today and one of the questions was about using a virtual method in C++ constructor. I failed this question, I answered that there shouldn't be any problem, however after reading this I found out I was wrong.
So I understand that the reason for not allowing that is because the derived object is not fully initialized and therefore calling it's virtual method can cause invalid consequences.
My question how was it solved in Java/C# ? I know that I can call derived method in my base constructor, I would assume that these languages have exactly the same problem.
Java has a very different object model from C++. In Java, you cannot have variables which are objects of class type -- instead, you can only ever have references to objects (of class type). Therefore, all members of a class (which are only references) start out trivially as null until the entire derived object has been set up in memory. Only then do the constructors run. Thus by the time a base constructor calls a virtual function, even if that function is overridden, the overridden function can at least correctly refer to members of the derived class. (Those members may not themselves be assigned yet, but at least they exist.)
(If it helps, you can also consider that every class without final members in Java is technically default-constructible, at least in principle: Unlike in C++, Java has no such things as constants or references (which must be initialized in C++), and in fact there are no initializer lists at all. Variables in Java simply don't need to be initialized. They're either primitives which start as 0, or class type references which start as null. One exception comes from non-static final class members, which cannot be rebound and must actually be "initialized" by having precisely one assignment statement somewhere in every constructor [thanks to #josefx for pointing this out!].)
understand that the reason for not allowing that is because the derived object is not fully initialized and therefore calling it's virtual method can cause invalid consequences
Wrong. C++ will call the base class's implementation of the method, not the derived class's. There are no 'invalid consequences'. The only valid reason for avoiding the construct is that the behavior sometimes comes as a surprise.
This is different from Java because Java calls the derived class's implementation.
In C++ every polymorphic class( class that has at least one virtual function ) has a hidden pointer at start of it( usually named v-table or something like that ) that will be initialized to the virtual table( an array of functions that point to the body of each virtual function ) of that class and when you call a virtual function C++ simply call ((v-table*)class)[index of your function]( function-parameters ), so if you call a virtual function in base class constructor v-table point to virtual table of the base class since your class is base and it still need some initialization to become child and as a result you will call implementation of the function from base not from child and if this is a pure virtual function you will get an access violation.
but in java this is not something like this, in java whole the class is something like std::map<std::string, JValue> in this case JValue is some variant type( for example a union or boost::variant ) when you call a function in constructor of base it will find function name in the map and call it, it is still not the value from the child but you can still call it and if you changed it in the prototype, since prototype created before your constructor you can successfully call function from child but if function required some initialization from constructor of the child you still get error or an invalid result.
so in general it is not a good practice to call a function from child( for example a virtual function ) in base class. if your class need to do this add an initialize method and call it from constructor of your child class.
Every Java constructor looks like this:
class Foo extends Bar {
Foo() {
super(); // creates Bar
// do things
}
}
So if you place code working on derived methods in do things, seems to be logic, that this base object was initialized properly, after calling its constructor in super();
I think that Java/C# avoid this problem by constructing from derived class backwards rather than in C++ from base class forwards.
Java implicitly calls super() in a classes constructor so by the time the first line of written code in a derived class constructor is called all the constructors of all inherited classes are guaranteed to have been called and so the new instance will have been completely initialised.
I think also in C++ a new instance of a class begins life as the base class and gets "upgraded" to the final class type as we move down the inheritance chain. This means that when you call a virtual function in the constructor you'll actually be calling the version of that function for the base class.
In Java and presumably C# a new instance starts life as the required class type so the correct version of the virtual method will be called.
Java does not entirely avoid the problem.
An overridden method called from a superclass constructor that depends on fields of the subclass will be called before those fields have been initialized.
If you're in control of the entire class hierarchy, you can of course just make sure your overrides don't depend on subclass fields. But it's safer to just not call virtual methods from constructors.

Best way to invoke method inhereted from Base class : use this , super or call implicitly

I think it's not very useful question, but i think someone can say smth critical.
public class Base{
public void boo(){}
}
public class Derivative extends Base{
1:public void useBoo(){
boo();
}
2:public void useBoo(){
this.boo();
}
3:public void useBoo(){
super.boo();
}
}
[EDIT]
The reason why I asked this question : to avoid recompilation or name confusion in future. And make code more readability and flexable to future changes.
The best one to use is the one you feel is clearest.
BTW: The first example will behave different to the third example, if you add a boo method to Derived.
If you want to be sure that the method invoked is the super class method, definitely use super:
super.boo();
If you want to use a method defined in the current class and if this is not present use the super method use:
this.boo();
//or
boo();
Personally in the second case, if the class is part of a hierarchy, I prefer to explicitly use this.boo() because it's more clear reading the code, to understand where the method is supposed to be. But it's my opinion.
I would only use 1 and 2 (in my case I prefer 2, I like to be explicit about my intentions)
public void useBoo(){
this.boo();
}
I wouldn't use 3 because it means something else semantically, remember that Derivative can also be extended, and boo() may be overridden further down the class hierarchy, and unless you specifically want to call Base.boo() you shouldn't use the super keyword.
Use one of the first two, unless you explicitly want to limit the call to the superclass implementation.
When you override a superclass method, and want to include the behavior of the superclass method, use the third.
Elsewhere, if you use the third, and later you or someone else overrides the superclass implementation of boo() -- in this class or a subclass -- then useBoo() will not use the override. This is usually undesirable except in the override of boo() itself.
Examples:
/** Extends boo method. */
public void boo(){
super.boo(); // Good: you explicitly want to call the superclass method, not call this method again.
}
public void doSomethingThatInvolvesBoo() {
boo(); // Good -- will call this object's implementation,
// even if this is a subclass, even if there are code changes later.
this.boo(); // Good (and equivalent to simply calling boo()).
super.boo(): // Usually bad.
}
Is there anything stopping you from just calling boo()? Or have you overridden it in your own code?
1 and 2 do the same thing, 3 calls the method of Base.
edit: as Simeon said, using super would make it very clear you are calling the method from the Base class.
Having readability in mind super is probably the best because it says here I'm invoking a method from the super class.
While with this you could wonder 'where the hell is this method .. oh ok its in the super class'

Categories

Resources