web-dev-qa-db-fra.com

Pourquoi devons-nous appeler super dans Android parfois?

Parfois, lorsque je substitue des méthodes, j'obtiens une exception la première fois qu'on l'appelle comme ci-dessous:

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()

Pourquoi sommes-nous obligés d'appeler super.method()? Il est logique que la classe parente ait des obligations, mais plus important encore, comment savons-nous qu’une méthode nécessite l’appel de super au lieu d’attendre qu’elle se bloque?

41
StackOverflowed

Pourquoi sommes-nous obligés d'appeler super.method ()?

Les classes qui composent le SDK Android peuvent être incroyablement complexes. Par exemple, les activités et les fragments doivent effectuer un certain nombre d’opérations pour fonctionner correctement (gestion du cycle de vie, optimisation de l’utilisation de la mémoire, affichage de la présentation à l’écran, etc.). Le fait de demander au client d'appeler la classe de base (souvent au début de la méthode) garantit que ces opérations sont toujours exécutées, tout en fournissant un niveau d'abstraction raisonnable au développeur.

Comment savons-nous qu'un une fonction méthode nécessite que super soit appelé? 

La documentation devrait vous dire si cela est nécessaire ou non. Si ce n'est pas le cas, je chercherai un exemple de code sur Google (ou vérifierai les démos de l'API ... ou mieux encore, examinez le code source!). Il ne devrait pas être trop difficile à comprendre.

39
Alex Lockwood

Je sais que ce n’est pas la véritable intention du PO, il a posé cette question et je ne pense pas qu’elle obtienne une très bonne réponse, alors, si quelqu'un se demande jamais "Pourquoi diable dois-je appeler super?!? Si? ils vont l'exiger, pourquoi ne le font-ils pas pour moi !!! ". Voici la réponse à cette question ....

En gros, super () est quelque chose qui doit être appelé si vous écrasez quelque chose qui DOIT être appelé, qui peut souvent être un code assez compliqué. Maintenant, la raison pour laquelle ils ne le font pas juste pour vous et l'appellent avant votre fonction est principalement pour que vous ayez le contrôle! :-RÉ

Pour être plus précis, vous ne pouvez pas contrôler SI vous appelez super (), cependant, vous pouvez contrôler WHEN! Donc, supposons que vous ayez du code spécifique à produire AVANT que super () soit appelé, vous avez maintenant la liberté. appeler super () seulement après avoir exécuté votre code. Ou ... supposons que vous ayez besoin que super () ait déjà exécuté votre code pour ne pas planter, vous avez maintenant la possibilité d'exécuter super () avant d'exécuter votre code, garantissant ainsi que tout est configuré pour vous. Heck, vous pouvez même techniquement remplacer le hardcore de la super-classe et coder votre propre méthode qui prend en charge super () lui-même et lui faire en sorte que vous n'ayez pas à appeler super (), mais 99,9% du temps, les personnes saines n'auront pas besoin pour faire ça! :-P

Donc, la réponse courte à "pourquoi dois-je appeler super ()" est ... Pour que vous puissiez contrôler quand il est appelé et faire les choses avant, ou après que super () soit exécuté. :-)

14
Jared

Le mot-clé super a deux utilisations principales

1. Appelle le constructeur de la superclasse.

2. Permet d'accéder à un membre de la superclasse masqué par un membre d'une sous-classe.

Alors, pourquoi avoir besoin de super mot-clé parfois? La réponse serait Android vient sous le langage 4GL ce qui signifie qu'il a beaucoup de fonctionnalités prêtes à l'emploi. Lorsque nous remplaçons ces méthodes pour la personnalisation, nous utilisons le mot-clé super. 

voyez l'utilisation très simple de super mot-clé dans Android (comme nous le faisons la plupart du temps).

@Override
public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    .
    .
    .
}

super () doit toujours être la première instruction exécutée dans le constructeur d’une sous-classe. Lorsqu'une sous-classe appelle super (), elle appelle le constructeur de sa super-classe immédiate. La deuxième forme de super s’applique le plus aux situations dans lesquelles les noms de membres d’une sous-classe masquent les membres du même nom dans la superclasse.

9
Lucifer

L'exigence est généralement spécifiée directement dans la documentation de l'API. Par exemple, voir Android.widget.ListView.onFinishInflate:

void protégé onFinishInflate ()

...

Même si la sous-classe remplace onFinishInflate, ils doivent toujours être sûrs d'appeler la super méthode pour pouvoir être appelés.

Malheureusement, mon expérience personnelle est que la qualité des documents Android est inégale. Donc, je soupçonne qu'il y a des cas où l'appel est requis mais n'est pas documenté en tant que tel.

3

En règle générale, super est une méthode utilisée pour désigner le champ/la méthode de la superclasse principal à partir duquel l'extension de classe est effectuée (à l'aide de expand dans la définition de classe initiale) ou à partir duquel l'instance est créée. 

Lorsque nous avons besoin d’une définition la plus élémentaire de la méthode/du champ de la super-classe à utiliser pour résoudre notre objectif.

par exemple 

Java.lang.Object (contient de nombreuses méthodes et champs)> Android.view.View> Android.view.ViewGroup> Android.widget.LinearLayout 

Mais si vous devez changer/utiliser car c'est une méthode de la classe d'objet, vous avez besoin de la méthode Super pour faire référence à la première méthode créée dans la classe d'objet dans La classe LinearLayout.

0
Rahul Joshi

Il est important de noter qu'une fois que vous avez redéfini une méthode, vous ignorez en gros tout ce qui se trouvait dans la classe parent. Vous avez plutôt votre propre implémentation personnalisée dans la classe enfant (la écrasant littéralement)!

Dans notre cas, nous ne voulons pas jeter l'implémentation parent. En fait, nous souhaitons continuer à utiliser la méthode d'origine et ajouter les contrôles supplémentaires pour chaque classe enfant individuellement.

C’est là que l’on utilise le mot clé "super"!

Vous êtes autorisé à réutiliser la méthode parente dans la classe enfant en utilisant le mot clé "super", suivi d'un point et du nom de la méthode: 

par exemple: isValidMove (position) est une méthode pour les pièces d’échecs et vérifier la validité des déplacements et être lié au tableau d’échecs 8x8.

super.isValidMove (position);

L'utilisation du mot clé super ici signifie que nous souhaitons exécuter la méthode dans la classe super (ou parent) à partir de l'implémentation de la classe "this".

Ce qui signifie que dans chacune des classes enfants, avant de pouvoir vérifier le mouvement personnalisé, vous pouvez vérifier si super.isValidMove (position) a renvoyé la valeur false. Si tel est le cas, inutile de faire d'autres vérifications et de renvoyer immédiatement faux; sinon, continuez à vérifier.

La nouvelle implémentation de la classe Rook ressemblera à ceci: 

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;
      }
   }
}

Vous pouvez également utiliser super () pour appeler le constructeur du parent. Cela se fait généralement lors de la mise en œuvre du constructeur de l'enfant. Généralement, vous voudrez tout d'abord tout exécuter dans le constructeur du parent, puis ajouter plus de code dans le constructeur de l'enfant:

class Rook extends Piece{
   // default constructor
   public Rook(){
    super(); // this will call the parent's constructor
    this.name = "rook";
   }
}

Remarque: Si le constructeur d'un enfant n'appelle pas explicitement le constructeur du parent à l'aide de super, le compilateur Java insère automatiquement un appel au constructeur par défaut de la classe parent. Si la classe parent n'a pas de constructeur par défaut, vous obtiendrez une erreur lors de la compilation.

0
Rahul Joshi