Wann soll die Methode super() beim Überschreiben NICHT aufgerufen werden?

Lesezeit: 7 Minuten

Benutzer-Avatar
Sandalen

Wenn ich meine eigene benutzerdefinierte Android-Klasse erstelle, kann ich extend seine einheimische Klasse. Wenn ich dann die Basismethode überschreiben möchte, rufe ich immer auf super() Methode, so wie ich es immer mache onCreate, onStopetc.

Und ich dachte, das ist es, denn von Anfang an riet uns das Android-Team, immer anzurufen super bei jeder Methodenüberschreibung.

Aber in viele Bücher Ich sehe, dass Entwickler, die erfahrener sind als ich, es oft unterlassen, anzurufen super und ich bezweifle wirklich, dass sie es aus Mangel an Wissen tun. Schauen Sie sich zum Beispiel dieses Basic an SAXOPHON Parser-Klasse wo super wird weggelassen 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 werden 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 kann man es weglassen anzurufen?

PS. Binden Sie sich nicht an dieses konkrete Beispiel. Es war nur ein zufällig ausgewähltes Beispiel aus vielen Beispielen.

(Das mag wie eine Anfängerfrage klingen, aber ich bin wirklich verwirrt.)

  • endElementDas API-Dokument von sagt: „Standardmäßig nichts tun. Anwendungsautoren 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 erkennen, ob Sie es tun müssen / können / sollten, wenn Sie das Dokument für diese Methode lesen.

    – zapl

    20. April 2012 um 11:07 Uhr

  • Kleines Beispiel: Ich verwende onBackPressed() im Begrüßungsbildschirm, und ich rufe NICHT super an, damit es nicht aus dem Begrüßungsfenster geht, es deaktiviert nur die Schaltfläche.

    – Bojan Kogoj

    25. April 2012 um 3:10 Uhr

Benutzer-Avatar
Xavi Lopez

Durch den Aufruf der super Methode, du bist es nicht überschreiben das Verhalten der Methode, du bist verlängern es.

Ein Anruf bei 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 könnte, in dem Sie anrufen super‘s-Implementierung in Ihrer Methode überschreibt. Zum Beispiel:

public class A { 
    public void save() { 
         // Perform save logic
    }
}

public class B extends A {
    private Object b;
    @Override
    public void save() { 
        super.save(); // Performs the save logic for A
        save(b); // Perform additional save logic
    }
}

Ein Anruf bei B.save() wird die durchführen save() Logik für beide A und B, in dieser bestimmten Reihenfolge. Wenn Sie nicht angerufen haben super.save() Innerhalb B.save(), A.save() würde nicht angerufen. Und wenn du angerufen hast super.save() nach save(b), A.save() würde danach effektiv durchgeführt werden B.save().

Wenn Sie wollen überschreiben super‘s Verhalten (das heißt, ignorieren Sie seine Implementierung vollständig und stellen Sie alles selbst bereit), sollten Sie nicht anrufen super.

In dem SAXParser Beispiel, das Sie angeben, die Implementierungen von DefaultHandler denn diese Methoden sind einfach leer, sodass Unterklassen sie überschreiben und ein Verhalten für diese Methoden bereitstellen können. In dem javadoc für diese Methode wird auch darauf hingewiesen.

public void startElement (String uri, String localName,
    String qName, Attributes attributes) throws SAXException {
    // no op
}

Über die super() Standardaufruf in Code, der von IDEs generiert wird, wie @barsju wies in seinem Kommentar darauf hin, dass es in jedem Konstruktor einen impliziten Aufruf von gibt super() (auch wenn Sie es nicht in Ihren Code schreiben), was in diesem Zusammenhang einen Aufruf von bedeutet superStandardkonstruktor von . Das IDE schreibt es einfach für Sie auf, aber es würde auch aufgerufen werden, wenn Sie es entfernen würden. Beachten Sie auch, dass beim Implementieren von Konstruktoren super() oder eine seiner Varianten mit Argumenten (dh super(x,y,z)) kann nur angerufen werden ganz am Anfang der Methode.

  • Beachten Sie dies auch nicht für Konstruktoren super() (der Standardkonstruktor der Superklasse) wird immer aufgerufen, auch wenn Sie ihn nicht angeben. Wenn die Oberklasse keinen Standardkonstruktor hat, erhalten Sie einen Kompilierungsfehler, wenn Sie nicht explizit einen der Konstruktoren der Oberklasse als erste Anweisung im Unterklassenkonstruktor aufrufen.

    – Barsju

    20. April 2012 um 10:55 Uhr

  • Ja, es ist im Grunde nur Faulheit – bei Methoden, von denen wir wissen, dass sie nichts bewirken, lassen Sie sie einfach der Kürze halber weg

    – Voo

    20. April 2012 um 10:59 Uhr

  • Vielen Dank für Ihre wertvollen Kommentare, @barjsu, ich habe diese Details in die Antwort aufgenommen.

    – Xavi Lopez

    20. April 2012 um 11:09 Uhr

Benutzer-Avatar
yorkw

Woher wissen sie, wann Sie Super anrufen müssen und wann Sie es unterlassen können, anzurufen?

Wenn eine spezielle API-Methode eine entscheidende Bedeutung für den Lebenszyklus des zugrunde liegenden Framework-Kontexts hat, wird sie in der API-Dokumentation normalerweise immer explizit angegeben und hervorgehoben, wie z Activity.onCreate() API-Dokumentation. Wenn die API einem robusten Design folgt, sollte sie außerdem einige Ausnahmen auslösen, um den Consumer-Entwickler zur Kompilierzeit des Projekts zu warnen und sicherzustellen, dass sie zur Laufzeit keinen Fehler generiert.

Wenn dies nicht ausdrücklich in der API-Dokumentation angegeben ist, kann der Consumer-Entwickler davon ausgehen, dass die API-Methode nicht zwingend aufgerufen werden muss, wenn sie überschrieben wird. Es liegt am Consumer-Entwickler, zu entscheiden, ob das Standardverhalten verwendet werden soll (rufen Sie die super -Methode) oder vollständig überschreiben.

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 der Haube geschrieben ist. Kasse Activity.onCreate() Quelle und DefaultHandler.startElement() Quelle zum Beispiel.

  • Danke, dass du mir weitere Dinge erklärt hast. Danke, dass Sie mich daran erinnern, den Quellcode zu überprüfen.

    – Sandalen

    21. April 2012 um 15:17 Uhr

Benutzer-Avatar
Michael

Der Test, den Sie in Ihrem Kopf machen sollten, ist:

“Möchte ich, dass die gesamte Funktionalität dieser Methode für mich erledigt wird, und dann etwas danach tun?” Wenn ja, dann wollen Sie anrufen super(), und beenden Sie dann Ihre Methode. Dies gilt für “wichtige” Methoden wie z onDraw()die viele Dinge im Hintergrund erledigt.

Wenn Sie nur einen Teil der Funktionalität benötigen (wie bei den meisten Methoden, die Sie überschreiben werden), möchten Sie wahrscheinlich nicht aufrufen super().

Brunnen Xavi gab eine bessere Antwort .. aber Sie wissen wahrscheinlich, was es tut super() tun, wenn es in einer überschriebenen Methode aufgerufen wird … es zeigt an, was Sie mit dem Standardverhalten gemacht haben.

z.B:

onDraw() 

Methode in der Ansichtsklasse, wenn sie überschrieben wird. Sie zeichnen etwas, bevor Sie super.onDraw () sagen. Es wird angezeigt, sobald die Ansicht vollständig gezeichnet ist super ist notwendig, da Android einige äußerst wichtige Dinge zu tun hat (wie onCreate())

aber zur selben Zeit

onLongClick()

Wenn Sie dies überschreiben, möchten Sie nicht super aufrufen, da es einen Dialog mit einer Liste von Optionen für eine EditText- oder eine andere ähnliche Ansicht aufruft. Das ist der grundlegende Unterschied. Sie haben manchmal die Wahl, es zu verlassen andere Methoden wie onCreate() , onStop() Sie sollten das Betriebssystem damit umgehen lassen.

Ich habe eine Constraint-Array-Liste wie implementiert

public class ConstraintArrayList<T> extends ArrayList<T> {
  ConstraintArrayList(Constraint<T> cons) {this.cons = cons;}
  @Override
  public boolean add(T element) {
    if (cons.accept(element))
      return super.add(element);
    return false;
  }
}

Wenn Sie sich den Code ansehen, führt er einfach einige Vorabprüfungen durch, bevor er die Superklasse tatsächlich das eigentliche Hinzufügen von Elementen zur Liste durchführt. Dies gibt einen der zwei Gründe für das Überschreiben von Methoden an:

  1. Erweiterbarkeit, wo Sie erweitern möchten, was die Superklasse kann
  2. Spezifität, wenn Sie durch Polymorphismus ein bestimmtes Verhalten hinzufügen möchten, wie im allgemeinen Tierreich-Beispiel der Bewegungssemantik, wo die Art und Weise, wie sich Vögel bewegen (fliegen) und Frösche bewegen (hüpfen), für jede Unterklasse spezifisch sind.

Benutzer-Avatar
Peter Mortensen

Ich habe Ihre Frage nicht klar verstanden, aber wenn Sie fragen, warum rufen Sie nicht an? super Methode:

Es gibt einen Grund für den Anruf super Methode: Wenn es in der übergeordneten Klasse keinen Konstruktor mit Nullargumenten gibt, ist es nicht möglich, dafür eine untergeordnete Klasse zu erstellen. Sie müssen also entweder einen Konstruktor ohne Argumente in der übergeordneten Klasse behalten oder definieren super() Calling-Anweisung mit argument(how much argument constructor you have used in super class) an der Spitze des untergeordneten Klassenkonstruktors.

Ich hoffe das hilft. Wenn nicht, lassen Sie es mich wissen.

Benutzer-Avatar
Dominik

Für diejenigen, die sich auch gefragt haben, welche überschriebenen Methoden von Android Framework aufgerufen werden sollen super und diese Frage gefunden – hier ein aktueller Hinweis aus 2019 – Android Studio 3+ sagt Ihnen, wann Sie es brauchen.

Geben Sie hier die Bildbeschreibung ein

1320570cookie-checkWann soll die Methode super() beim Überschreiben NICHT aufgerufen werden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy