Wenn ich meine eigene benutzerdefinierte Android-Klasse erstelle, ist dies extend
die native Klasse. Dann , wenn ich die Basismethode außer Kraft setzen wollen, habe ich immer anrufen super()
Methode, so wie ich es immer tue in onCreate
, onStop
usw.
Und ich dachte, das ist es, da das Android-Team uns von Anfang an geraten hat, immer super
jede Methodenüberschreibung aufzurufen .
Aber in vielen Büchern kann ich sehen, dass Entwickler, die erfahrener sind als ich, das Anrufen oft unterlassen, super
und ich bezweifle wirklich, dass sie dies aus Mangel an Wissen tun. Schauen Sie sich zum Beispiel diese grundlegende SAX- Parser-Klasse an, super
in der weggelassen wird startElement
, characters
und 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
}
}
}
Wenn Sie versuchen, eine Überschreibungsmethode über Eclipse oder eine andere IDE zu erstellen, super
wird diese immer als Teil eines automatisierten Prozesses erstellt.
Dies war nur ein einfaches Beispiel. Bücher sind voll von ähnlichem Code .
Woher wissen sie, wann Sie anrufen müssen super
und wann Sie das Anrufen unterlassen können?
PS. Binden Sie nicht an dieses spezielle Beispiel. Es war nur ein Beispiel, das zufällig aus vielen Beispielen ausgewählt wurde.
(Das klingt vielleicht nach einer Anfängerfrage, aber ich bin wirklich verwirrt.)
quelle
endElement
Das API-Dokument lautet "Standardmäßig nichts tun. Anwendungsschreiber können diese Methode überschreiben ...", was bedeutet, dass Sie Super sicher aufrufen können, weil es "nichts" tut, aber Sie müssen es nicht und Sie können es wirklich überschreiben. Sie können oft feststellen, ob Sie dies tun müssen / können / sollten, wenn Sie das Dokument für diese Methode lesen.Antworten:
Durch das Aufrufen der
super
Methode überschreiben Sie nicht das Verhalten der Methode, sondern erweitern es.Ein Aufruf von
super
führt jede Logik aus, die die Klasse, die Sie erweitern, für diese Methode definiert hat. Berücksichtigen Sie, dass es in dem Moment wichtig sein kann, in dem Sie diesuper
Implementierung in Ihrer Methode überschreiben. Zum Beispiel:Ein Aufruf von
B.save()
führt diesave()
Logik für beideA
undB
in dieser bestimmten Reihenfolge aus. Wenn Sie nichtsuper.save()
drinnen anrufen würdenB.save()
,A.save()
würden Sie nicht angerufen werden. Und wenn Sie riefsuper.save()
nachsave(b)
,A.save()
würde effektiv danach durchgeführt werdenB.save()
.Wenn Sie das Verhalten überschreiben möchten
super
(dh die Implementierung vollständig ignorieren und alles selbst bereitstellen möchten ), sollten Sie nicht anrufensuper
.Im
SAXParser
Beispiel , das Sie zur Verfügung stellen, die Implementierungen vonDefaultHandler
sind für diese Methoden nur leer, so dass Subklassen sie außer Kraft setzen kann und ein Verhalten für diese Methoden zur Verfügung stellen. Im Javadoc für diese Methode wird auch darauf hingewiesen.Über den
super()
von IDEs generierten Standardaufruf in Code, wie@barsju
in seinem Kommentar ausgeführt, gibt es in jedem Konstruktor einen impliziten Aufruf vonsuper()
(auch wenn Sie ihn nicht in Ihren Code schreiben), was in diesem Zusammenhang einen Aufruf vonsuper
'bedeutet. s Standardkonstruktor. DasIDE
schreibt es nur für Sie auf, aber es würde auch aufgerufen, wenn Sie es entfernen. Beachten Sie auch, dass bei der Implementierung von Konstruktorensuper()
oder einer ihrer Varianten mit Argumenten (dhsuper(x,y,z)
) nur ganz am Anfang der Methode aufgerufen werden kann .quelle
super()
(der Standardkonstruktor der Superklasse) immer aufgerufen wird, auch wenn Sie ihn nicht angeben. Wenn die Superklasse keinen Standardkonstruktor hat, wird ein Kompilierungsfehler angezeigt, wenn Sie einen der Konstruktoren der Superklasse nicht explizit als Ihre erste Anweisung im Unterklassenkonstruktor aufrufen.Wenn eine spezielle API-Methode eine kritische Bedeutung für den zugrunde liegenden Framework-Kontext-Lebenszyklus hat, wird sie normalerweise wie die
Activity.onCreate()
API-Dokumentation in der API-Dokumentation immer explizit angegeben und hervorgehoben . Wenn die API einem robusten Design folgt, sollte sie außerdem einige Ausnahmen auslösen, um den Consumer-Entwickler zur Kompilierungszeit des Projekts zu warnen und sicherzustellen, dass zur Laufzeit kein Fehler generiert wird.Wenn dies in der API-Dokumentation nicht explizit angegeben ist, kann der Consumer-Entwickler davon ausgehen, dass die API-Methode beim Überschreiben nicht unbedingt aufgerufen werden muss. Es ist Sache des Consumer-Entwicklers, zu entscheiden, ob das Standardverhalten verwendet (
super
Methode aufrufen ) oder vollständig überschrieben werden soll.Wenn die Bedingung zulässig ist (ich liebe Open-Source-Software), kann der Consumer-Entwickler jederzeit den API-Quellcode überprüfen und sehen, wie die Methode tatsächlich unter die Haube geschrieben wird. Schauen Sie sich zum Beispiel
Activity.onCreate()
Quelle undDefaultHandler.startElement()
Quelle an.quelle
Der Test, den Sie in Ihrem Kopf machen sollten, ist:
"Möchte ich die gesamte Funktionalität dieser Methode für mich erledigen und danach etwas tun?" Wenn ja, möchten Sie aufrufen
super()
und dann Ihre Methode beenden. Dies gilt für "wichtige" Methoden wieonDraw()
, die viele Dinge im Hintergrund behandeln.Wenn Sie nur einen Teil der Funktionalität wünschen (wie bei den meisten Methoden, die Sie überschreiben werden), möchten Sie wahrscheinlich nicht aufrufen
super()
.quelle
Nun, Xavi hat eine bessere Antwort gegeben. Aber Sie wissen wahrscheinlich, was zu
super()
tun ist, wenn Sie eine überschriebene Methode aufrufen. Es zeigt an, was Sie mit dem Standardverhalten gemacht haben.z.B:
Methode in der View-Klasse, wenn sie überschrieben wird. Sie zeichnen etwas, bevor Sie super.onDraw () sagen. Es wird angezeigt, sobald die Ansicht vollständig gezeichnet ist. Hier ist ein Aufruf
super
erforderlich, da Android einige wichtige Dinge zu tun hat (wie onCreate ()).aber zur selben Zeit
Wenn Sie dies überschreiben, möchten Sie nicht super aufrufen, da ein Dialogfeld mit einer Liste von Optionen für einen EditText oder eine andere ähnliche Ansicht angezeigt wird. Dies ist der grundlegende Unterschied. Sie haben die Wahl, ihn einige Male zu belassen. Aber für andere Methoden wie
onCreate() , onStop()
Sie sollten das Betriebssystem damit umgehen lassen ..quelle
Ich habe Ihre Frage nicht klar verstanden, aber wenn Sie sich fragen, warum Sie die
super
Methode nicht aufrufen :Es gibt einen Grund für den Aufruf der
super
Methode: Wenn es in der übergeordneten Klasse keinen Null-Argument-Konstruktor gibt, ist es nicht möglich, eine untergeordnete Klasse dafür zu erstellen. Entweder müssen Sie einen Konstruktor ohne Argumente in der übergeordneten Klasse behalten, oder Sie benötigen zu definierensuper()
Aufruf - Anweisung mitargument(how much argument constructor you have used in super class)
an der Spitze des Kindes Klassenkonstruktors.Ich hoffe das hilft. Wenn nicht, lass es mich wissen.
quelle
Ich habe eine Constraint-Array-Liste wie implementiert
Wenn Sie sich den Code ansehen, wird lediglich eine Vorprüfung durchgeführt, bevor die Superklasse das eigentliche Hinzufügen eines Elements zur Liste durchführt. Dies ist einer der beiden Gründe für das Überschreiben von Methoden:
quelle
Für diejenigen, die sich auch gefragt haben, welche überschriebenen Methoden von Android Framework
super
diese Frage aufrufen und finden sollen - hier ist ein aktueller Hinweis aus dem Jahr 2019 -, wird Android Studio 3+ Ihnen sagen, wann Sie sie benötigen .quelle