wake-up-neo.com

Warum müssen wir in Android manchmal super anrufen?

Wenn ich Methoden überschreibe, erhalte ich manchmal eine Ausnahme, wenn sie zum ersten Mal wie folgt aufgerufen wird:

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

Warum müssen wir super.method() anrufen? Es ist sinnvoll, dass es von der übergeordneten Klasse Verpflichtungen gibt, aber, was noch wichtiger ist, woher wissen wir, dass eine Methode den Aufruf von super erfordert und nicht darauf wartet, dass sie abstürzt?

41
StackOverflowed

Warum müssen wir super.method () aufrufen?

Die Klassen, aus denen das Android SDK besteht, können unglaublich komplex sein. Zum Beispiel müssen sowohl Aktivitäten als auch Fragmente eine Reihe von Operationen ausführen, um ordnungsgemäß zu funktionieren (d. H. Den Lebenszyklus verwalten, die Speichernutzung optimieren, das Layout auf den Bildschirm zeichnen usw.). Durch die Aufforderung an den Client, die Basisklasse aufzurufen (häufig am Anfang der Methode), wird sichergestellt, dass diese Vorgänge weiterhin ausgeführt werden, während gleichzeitig für den Entwickler ein angemessener Abstraktionsgrad zur Verfügung steht.

Woher wissen wir das? funktion Methode erfordert super aufgerufen zu werden? 

Die Dokumentation sollte Ihnen sagen, ob dies erforderlich ist oder nicht. Wenn nicht, würde ich mit Google nach Beispielcode suchen (oder die API-Demos überprüfen ... oder besser noch, schauen Sie sich den Quellcode an!). Es sollte nicht zu schwierig sein, dies herauszufinden.

39
Alex Lockwood

Ich weiß, dass dies nicht die wahre Absicht des OP ist, er hat diese Frage gestellt und ich glaube nicht, dass sie eine sehr gute Antwort erhalten hat. Wenn also jemals jemand sich gefragt hat: "Warum zum Teufel muss ich super nennen?!? Sie werden es fordern, warum tun sie es nicht einfach für mich? " Hier ist die Antwort auf diese Fragen ....

Im Allgemeinen ist super () etwas, das aufgerufen werden muss, wenn Sie etwas überschreiben, das MÜSSEN genannt werden muss, was oft recht komplizierter Code sein kann. Nun, der Grund, warum sie es nicht einfach für Sie tun und vor Ihrer Funktion aufrufen, ist meistens so, dass Sie die Kontrolle haben! :-D

Um genauer zu sein, können Sie nicht kontrollieren, WENN Sie super () aufrufen, Sie können jedoch WHEN! .__ kontrollieren. Nehmen wir an, Sie haben einen bestimmten Code, der ausgeführt werden muss, BEVOR super () aufgerufen wird. Jetzt haben Sie die Freiheit um super () nur nach dem Ausführen Ihres Codes aufzurufen. Oder ... Nehmen wir einmal an, Sie benötigen super (), damit Ihr Code nicht abstürzt. Sie haben jetzt die Möglichkeit, super () auszuführen, bevor Sie den Code ausführen, um sicherzustellen, dass alles für Sie eingerichtet ist. Heck, Sie könnten sogar den Superclass-Hardcore technisch übersteuern und Ihre eigene Methode codieren, die sich super () selbst kümmert, und so machen, dass Sie nicht super () aufrufen müssen, aber 99,9% der Zeit, die gesunde Menschen nicht brauchen werden um dies zu tun! :-P

Also, die kurze Antwort auf "Warum muss ich super () aufrufen?" ... Damit Sie kontrollieren können, wann es aufgerufen wird und Dinge vor oder nach super () ausgeführt werden. :-)

14
Jared

Das Schlüsselwort super hat zwei Hauptanwendungen

1. Ruft den Konstruktor der Superklasse auf.

2. Zugriff auf ein Mitglied der Superklasse, das von einem Mitglied einer Unterklasse ausgeblendet wurde.

Also, warum muss man manchmal Super-Keywords verwenden? Die Antwort wäre, dass Android unter der Sprache 4GL läuft, was bedeutet, dass es viele Funktionen bereitstellt. Während wir diese Methoden für die Anpassung überschreiben, verwenden wir das Schlüsselwort super. 

sehen Sie sich die sehr einfache Verwendung des Super-Keywords in Android an (wie wir es meistens tun).

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

super () muss immer die erste Anweisung sein, die im Konstruktor einer Unterklasse ausgeführt wird. Wenn eine Unterklasse super () aufruft, ruft sie den Konstruktor seiner unmittelbaren Superklasse auf. Die zweite Form von Super ist am besten auf Situationen anwendbar, in denen Mitgliedsnamen einer Unterklasse Mitglieder mit demselben Namen in der Oberklasse verbergen.

9
Lucifer

Die Anforderung wird im Allgemeinen direkt in der API-Dokumentation angegeben. Siehe beispielsweise Android.widget.ListView.onFinishInflate:

protected void onFinishInflate ()

...

Selbst wenn die Unterklasse onFinishInflate überschreibt, sollten Sie immer die super-Methode aufrufen, damit wir aufgerufen werden.

Meine persönliche Erfahrung ist leider, dass Android-Dokumente in der Qualität unterschiedlich sind. Ich vermute also, dass es Fälle gibt, in denen der Anruf erforderlich ist, aber nicht als solcher dokumentiert ist.

3

Als Basis ist super eine Methode, die verwendet wird, um auf das Haupt-Superklassenfeld/die Hauptmethode zu verweisen, von der die Klassenerweiterung (mit Erweiterungen in der ursprünglichen Klassendefinition) oder deren Instanz erstellt wird. 

Wenn eine grundlegendste Definition der Methode/des Feldes der Oberklasse erforderlich ist, die zur Lösung unseres Zwecks verwendet werden soll.

zum Beispiel 

Java.lang.Object (hat viele Methoden und Felder)> Android.view.View> Android.view.ViewGroup> Android.widget.LinearLayout 

Wenn Sie jedoch eine Methode der Object-Klasse ändern/verwenden müssen, benötigen Sie die Super-Methode, um die zuerst erstellte Methode in der Objektklasse innerhalb der Klasse der LinearLayout-Klasse zu referenzieren.

0
Rahul Joshi

Es ist wichtig zu wissen, dass Sie nach dem Überschreiben einer Methode im Wesentlichen alles in der übergeordneten Klasse ignorieren und stattdessen Ihre eigene benutzerdefinierte Implementierung in der untergeordneten Klasse verwenden (die sie buchstäblich überschreibt)!

In unserem Fall möchten wir die übergeordnete Implementierung nicht wegwerfen. Wir möchten die ursprüngliche Methode tatsächlich weiterhin verwenden und die zusätzlichen Prüfungen für jede untergeordnete Klasse einzeln hinzufügen.

Hier können wir das Schlüsselwort "Super" verwenden!

Sie können die übergeordnete Methode in der untergeordneten Klasse erneut verwenden, indem Sie das Schlüsselwort "super" gefolgt von einem Punkt und dem Methodennamen verwenden: 

beispiel: isValidMove (Position) ist eine Methode für Schachfiguren und überprüft die Gültigkeit der Zugbewegungen und ist im 8x8-Schachbrett gebunden.

super.isValidMove (Position);

Die Verwendung des Schlüsselworts super bedeutet hier, dass die eigentliche Methode in der übergeordneten Klasse (oder der übergeordneten Klasse) aus der Implementierung in der Klasse "this" ausgeführt werden soll.

Was bedeutet, dass in jeder der untergeordneten Klassen vor der Überprüfung der benutzerdefinierten Bewegung geprüft werden kann, ob super.isValidMove (position) den Wert false zurückgegeben hat. Wenn ja, dann müssen Sie keine weiteren Prüfungen mehr durchführen und sofort false zurückgeben. Andernfalls fahren Sie mit der Überprüfung fort.

Die neue Implementierung für die Rook-Klasse sieht folgendermaßen aus: 

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

Sie können auch super () verwenden, um den Konstruktor des übergeordneten Elements aufzurufen. Dies geschieht normalerweise bei der Implementierung des Konstruktors des Kindes. Normalerweise möchten Sie zunächst alles im Konstruktor des übergeordneten Elements ausführen und dann mehr Code im Konstruktor des untergeordneten Objekts hinzufügen:

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

Anmerkung: Wenn der Konstruktor eines untergeordneten Objekts den Konstruktor des übergeordneten Objekts nicht explizit mit super aufruft, fügt der Java-Compiler automatisch einen Aufruf des Standardkonstruktors der übergeordneten Klasse ein. Wenn die übergeordnete Klasse über keinen Standardkonstruktor verfügt, wird ein Fehler bei der Kompilierung angezeigt.

0
Rahul Joshi