Why do we have to call super in Android sometimes?

2020-01-27 01:01发布

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?

6条回答
放我归山
2楼-- · 2020-01-27 01:31

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.

查看更多
家丑人穷心不美
3楼-- · 2020-01-27 01:34

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. :-)

查看更多
Deceive 欺骗
4楼-- · 2020-01-27 01:38

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.

查看更多
Lonely孤独者°
5楼-- · 2020-01-27 01:39

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.

查看更多
神经病院院长
6楼-- · 2020-01-27 01:42

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.

查看更多
再贱就再见
7楼-- · 2020-01-27 01:42

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.

查看更多
登录 后发表回答