Lorsque je crée ma propre classe personnalisée Android, je suis extend
sa classe native. Ensuite , quand je veux remplacer la méthode de base, je fais toujours appel super()
méthode, tout comme je le fais toujours onCreate
, onStop
etc.
Et je pensais que c'était ça, car dès le début, l'équipe Android nous a conseillé de toujours appeler super
chaque remplacement de méthode.
Mais, dans de nombreux livres, je peux voir que les développeurs, plus expérimentés que moi, omettent souvent d'appeler super
et je doute vraiment qu'ils le fassent par manque de connaissances. Par exemple, regardez cette classe d'analyseur SAX de base où super
est omis dans startElement
, characters
et 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
}
}
}
Si vous essayez de créer une méthode de remplacement via Eclipse ou tout autre IDE, elle super
sera toujours créée dans le cadre d'un processus automatisé.
Ce n’était qu’un simple exemple. Les livres regorgent de codes similaires .
Comment savent-ils quand vous devez appeler super
et quand vous pouvez l'omettre?
PS. Ne vous liez pas à cet exemple spécifique. C'était juste un exemple choisi au hasard parmi de nombreux exemples.
(Cela peut sembler une question de débutant, mais je suis vraiment confus.)
la source
endElement
Le document de l'API de l'API dit "Par défaut, ne faites rien. Les développeurs d'applications peuvent remplacer cette méthode ...", ce qui signifie que vous pouvez appeler super en toute sécurité car il ne fait "rien" mais vous n'êtes pas obligé et vous pouvez vraiment le remplacer. Vous pouvez souvent dire si vous devez / pouvez / ne devriez pas le faire si vous lisez la documentation de cette méthode.Réponses:
En appelant la
super
méthode, vous ne remplacez pas le comportement de la méthode, vous l' étendez .Un appel à
super
exécutera toute logique que la classe que vous étendez a définie pour cette méthode. Tenez compte du fait que cela peut être important au moment où vous appelez lsuper
'implémentation de votre méthode en remplaçant. Par exemple:Un appel à
B.save()
exécutera lasave()
logique pour les deuxA
etB
, dans cet ordre particulier. Si vous n'appeliez pas à l'super.save()
intérieurB.save()
, vousA.save()
ne seriez pas appelé. Et si vous appeliezsuper.save()
aprèssave(b)
,A.save()
serait effectivement exécuté par la suiteB.save()
.Si vous voulez remplacer
super
le comportement de (c'est-à-dire ignorer complètement son implémentation et tout fournir vous-même), vous ne devriez pas appelersuper
.Dans l'
SAXParser
exemple que vous fournissez, les implémentations deDefaultHandler
pour ces méthodes sont simplement vides, de sorte que les sous-classes peuvent les remplacer et fournir un comportement pour ces méthodes. Dans le javadoc de cette méthode, cela est également souligné.À propos de l'
super()
appel par défaut dans le code généré par les IDE, comme@barsju
indiqué dans son commentaire, dans chaque constructeur il y a un appel implicite àsuper()
(même si vous ne l'écrivez pas dans votre code), ce qui signifie, dans ce contexte, un appel àsuper
' constructeur par défaut. LeIDE
écrit simplement pour vous, mais il sera également appelé si vous le supprimez. Notez également que lors de l'implémentation de constructeurs,super()
ou l'une de ses variantes avec des arguments (iesuper(x,y,z)
) ne peut être appelée qu'au tout début de la méthode.la source
super()
(le constructeur par défaut de la super classe) est toujours appelé, même si vous ne le spécifiez pas. Si la super classe n'a pas de constructeur par défaut, vous obtiendrez une erreur de compilation si vous n'appelez pas explicitement l'un des constructeurs de la super classe comme première instruction dans le constructeur de sous-classe.Habituellement, si une méthode API spéciale a une signification critique pour le cycle de vie du contexte du framework sous-jacent, elle sera toujours explicitement indiquée et mise en évidence dans la documentation de l'API, comme la
Activity.onCreate()
documentation de l' API . De plus, si l'API suit une conception robuste, elle doit lever des exceptions pour alerter le développeur consommateur au moment de la compilation du projet et s'assurer qu'elle ne générera pas d'erreur au moment de l'exécution.Si cela n'est pas explicitement indiqué dans la documentation de l'API, il est tout à fait sûr pour le développeur consommateur de supposer que l'appel de la méthode API n'est pas obligatoire lors de la substitution. Il appartient au développeur consommateur de décider d'utiliser le comportement par défaut (appeler la
super
méthode) ou de le remplacer complètement.Si la condition est autorisée (j'aime les logiciels open-source), le développeur consommateur peut toujours consulter le code source de l'API et voir comment la méthode est réellement écrite sous le capot. Vérifiez la
Activity.onCreate()
source et laDefaultHandler.startElement()
source par exemple.la source
Le test que vous devriez faire dans votre tête est:
"Est-ce que je veux que toutes les fonctionnalités de cette méthode soient faites pour moi, puis faire quelque chose après?" Si oui, vous souhaitez appeler
super()
, puis terminer votre méthode. Cela sera vrai pour les méthodes "importantes" telles queonDraw()
, qui gère beaucoup de choses en arrière-plan.Si vous ne voulez que certaines fonctionnalités (comme avec la plupart des méthodes que vous remplacerez), vous ne voudrez probablement pas appeler
super()
.la source
Eh bien, Xavi a donné une meilleure réponse ... mais vous savez probablement ce que fait
super()
une méthode surchargée ... il annonce ce que vous avez fait avec le comportement par défaut.par exemple:
méthode en classe de vue en cas de substitution .. vous dessinez quelque chose avant de dire super.onDraw () il apparaît une fois la vue est entièrement utilisé .. alors voici l' appel
super
est nécessaire , car Android a des choses extrêmement importantes à faire (comme onCreate ())mais en même temps
lorsque vous remplacez cela, vous ne voulez pas appeler super car il ouvre une boîte de dialogue avec une liste d'options pour un EditText ou toute autre vue similaire .. C'est la différence de base .. vous avez le choix de le laisser quelques fois .. mais pour d'autres méthodes comme
onCreate() , onStop()
vous devriez laisser le système d'exploitation le gérer.la source
Je n'ai pas compris votre question clairement, mais si vous demandez pourquoi ne pas appeler la
super
méthode:Il y a une raison pour appeler la
super
méthode: s'il n'y a pas de constructeur d'argument zéro dans la classe parente, il n'est pas possible de créer une classe enfant pour cela, donc soit vous devez garder un constructeur sans argument dans la classe parente, soit vous avez besoin pour définirsuper()
l'instruction d'appel avecargument(how much argument constructor you have used in super class)
en haut du constructeur de classe enfant.J'espère que ça aide. Sinon, faites-le moi savoir.
la source
J'ai implémenté une liste de tableaux de contraintes comme
Si vous regardez le code, il effectue simplement une vérification préalable avant de laisser la super classe effectuer l'ajout réel d'élément à la liste. Cela indique l'une des deux raisons de la substitution de méthode:
la source
Pour ceux qui se demandaient également quelles méthodes remplacées d'Android Framework devraient appeler
super
et ont trouvé cette question - voici un indice actuel de 2019 - Android Studio 3+ vous dira quand vous en avez besoin .la source