Java - Sollen ActionListeners, KeyListeners usw. in inneren Klassen erklärt werden?

8

In allen Java-Quellcode-Beispielen, die ich mir angeschaut habe, wurden die Listener immer in inneren Klassen deklariert.

Warum - was ist der Grund dafür, die Klassen so zu codieren, anstatt die Listener in ihrer eigenen * .java-Datei \ Klasse zu haben?

Würde es für ein schlechtes Design gehalten sein, getrennte Klassen für die Zuhörer zu haben?

Wenn es sich nicht um ein schlechtes Design \ sackbares Vergehen handelt, könnte jemand bitte ein kurzes Beispiel veröffentlichen, das zeigt, wie man das implementiert?

Danke fürs Lesen.

Bearbeiten \ Update - 10.8.2010: Danke an alle, die sich die Zeit genommen haben zu antworten. Viele aufschlussreiche Punkte zu beachten. Nachdem ich alle Antworten gelesen habe, denke ich, dass es besser und einfacher ist, Hörer als innere Klassen zu deklarieren, wenn es keinen guten Grund dafür gibt.

Entschuldigung dafür, dass ich nicht früher auf diese Frage zurückgekommen bin, aber ich habe nicht immer so viel Zeit zum Programmieren, wie ich möchte: - (

Glückliche Codierung.

    
The Thing 08.08.2010, 22:26
quelle

6 Antworten

6

Gute Gründe für die Verwendung innerer Klassen:

  • Vermeidet das Hinzufügen zusätzlicher Klassen der obersten Ebene zu Ihrem Paketnamespace
  • Hält den Code lokal gekapselt (z. B. in der Komponente, die das Ereignisbehandlungsverhalten erfordert)
  • statische innere Klassen funktionieren gut, wenn sie nicht auf Felder der einschließenden Klasse zugreifen müssen

Mögliche Gründe für die Verwendung von Top-Level-Klassen:

  • Sie haben einen speziellen Typ von Listener, von dem Sie erwarten, dass er von externen Paketen oder Formularen verwendet wird, die Teil Ihrer API sind (z. B. in der Java-Klassenbibliothek selbst)
  • Der Listener wird an vielen Stellen verwendet und ist nicht logisch spezifisch für eine der vielen einschließenden Klassen

Kurz gesagt: Normalerweise werden innere Klassen bevorzugt, aber wenn Sie gute Gründe haben, kann es durchaus sinnvoll sein, stattdessen Top-Level-Klassen zu erstellen.

    
mikera 08.08.2010, 22:48
quelle
1

Nein, ich denke nicht, dass sie immer innere Klassen sein sollten. Es impliziert, dass die Benutzeroberfläche selbst immer weiß, wie sie den Listener am besten auswählt.

Eine andere Möglichkeit, es zu betrachten, könnte sein, dass Listener in die Benutzeroberfläche eingefügt werden. Möglicherweise werden sie vom Controller bereitgestellt, der die Benutzeroberfläche instanziiert und ihr mitteilt, wie sie auf Benutzeroberflächenereignisse reagieren soll.

Ich denke, das ist eher eine Abhängigkeitsinjektion der Welt. Dies kann wichtige Vorteile haben.

    
duffymo 08.08.2010 23:22
quelle
1

Diese Antwort behandelt die Kompromisse zwischen den verschiedenen Möglichkeiten.

Die grundlegende Antwort ist, dass der GUI-Code in einem Programm normalerweise ziemlich eng verwoben ist und normalerweise nicht zwischen Programmen geteilt werden kann. Wenn Sie innere Klassen verwenden (insbesondere wenn Sie die oben beschriebene Antwort verwenden), können Sie den GUI-Code so strukturieren, dass er wartbar ist, während Sie akzeptieren, dass die GUI stark gekoppelt ist.

    
TofuBeer 09.08.2010 00:00
quelle
0

Wenn Sie sie in Beispielen gesehen haben, ist es wahrscheinlich einfacher. Die meisten werden Ihnen wahrscheinlich sagen, dass Sie nur Ihre aktuelle Klasse nehmen und den Listener implementieren. Was sieht einfacher aus: Erstellen Sie 2 Klassen in 2 Dateien, verwenden Sie einen verschachtelten Listener innerhalb einer Hauptklasse oder haben Sie einfach Ihre Hauptklasse als Listener? (Tipp: Es ist nicht der erste)

Ich bin faul und habe nur eine Hauptklasse implementiert die ActionListener-Schnittstelle. Dies funktioniert natürlich nur auf sehr einfachen GUIs. Bei größeren Projekten sollten Sie sie trennen.

Wenn Sie den Listener in einer separaten Klasse halten möchten, fragen Sie sich: Müssen andere Klassen dies verwenden? Klassen sollten NUR in einer eigenen Datei sein, wenn andere sie verwenden müssen. Und das Teilen von Listenern ist nicht gerade die beste Idee, es sei denn, Sie haben ein seltsames Layout, bei dem Schaltflächen das Gleiche tun, aber für jede Klasse anders angeordnet sind.

Kurz gesagt: Bewahre sie verschachtelt oder implementiert auf, nicht getrennt, wenn es nicht notwendig ist. Ein notwendiger Fall wäre jedoch wenige und weit zwischen

    
TheLQ 08.08.2010 22:48
quelle
0

Sie könnten den Listener natürlich in einer separaten Klassendatei in einer separaten .java-Datei implementieren lassen. Java 1.1 führte die Idee der anonymen Klasse und der inneren Klasse zusammen mit dem awt event redesign vor Jahren ein. Der Grund dafür ist, dass die Listener, die Sie schreiben, oft die Felder der Klasse, die die Objekte enthält, in denen Ereignisse generiert werden, aktualisieren und / oder lesen müssen. Es ist umständlich, diese Felder aus einer nicht-inneren / anonymen Klasse zu referenzieren.

Sobald Sie anonyme Klassen mehr verwenden, werden Sie sehen, dass es die Dinge einfacher macht, später zu schreiben und zu pflegen. Moderne IDEs generieren sogar den größten Teil des Codes für Sie. Geben Sie zum Beispiel in IntelliJ IDEA diese beiden Zeilen ein und drücken Sie Strg-Shift-Leerzeichen. IntellJ fügt eine anonyme Klasse ein, die alle Methoden der von addActionListener () angegebenen Schnittstelle implementiert.

%Vor%     
Gary 08.08.2010 23:00
quelle
0

Eine innere Klasse ist lokal für die aktuelle Klasse, was in Ordnung ist, falls diese nicht anderweitig verwendet werden müssen. In einem Beispiel in einem Buch gibt es der Klasse einen Namen , der es ermöglicht, leicht auf Prosa zu verweisen.

Die typische Verwendung für Zuhörer ist, dass sie nur an einem einzigen Ort verwendet werden und zu diesem Zweck die anonymen inneren Klassen perfekt sind. Für Schnittstellen mit vielen Methoden (wie MouseListeners) gibt es normalerweise einen entsprechenden Adapter mit leeren Implementierungen von allem, die dann bei Bedarf überschrieben werden können. Siehe MouseAdapter.

    
quelle

Tags und Links