Warum genau hat man einen Listener, dann ein Event und was ist ein Adapter

Kelsjb7

Mitglied
Hi, was ist die Aufgabe vom Listener und vom Event?

Also ich weiß, wie ich das verwende, was ich mich halt frage ist, warum hat man das getrennt? Also welchen Sinn hat das?

Was ist die Aufgabe vom Listener? Das Event führt ja Sachen aus, so weit ich weiß und ich auch nutze und im Listener gibt es halt die Methode.

Aber was genau ist der Listener, also für was ist der da?

Und was sind Adapter-Klassen? Welchen Zweck haben die, habe 0 gecheckt im Inet.

Und was ich mich auch frage ist, was tut getsource?
Wenn man getsourc beim Event nutzt, kann man das anscheinend casten wie man will, was tut dann getsource überhaupt, wenn ich danach casten darf wie ich will?

Danke für die Hilfe
 
Beste Antwort
K
Man versucht immer, Klassen so unabhängig wie möglich zu halten.

Und mit Hilfe von Abstraktionen kann man hier einiges an Unabhängigkeit erreichen.
Dies erreicht man z.B. über Interfaces. Dir ist egal, was für ein Auto du fährst - es muss aber das Interface AutoMitSchaltgetriebe haben.

Dieser erste Schritt Klassen unabhängig zu machen, reicht aber leider nicht ganz. Das ist super, denn eine Instanz fest auf eine andere zugreifen will. Aber nun kann es sein, dass es weitere Klassen gibt, die noch gar nicht bekannt sind. Wenn das Auto einen Unfall hat, dann soll irgend etwas automatisch passieren. Was genau weiss man aber nicht, wenn man das Auto baut. Das weisst auch Du nicht, der das Auto später baut. Also baut man das einfach als...
Ein Event "führt" nichts aus. Das Event ist einfach nur ein Objekt, welches ein Ereignis repräsentiert (z.B. ein Mouse-Button-Click auf einer UI - mit entsprechenden Informationen wie der Koordinate).
Einem oder mehreren registrierten Listenern wird dann von demjenigen, der das Event/Ereignis produziert, das Event übergeben, indem dieser jemand auf dem Listener die entsprechende Methode aufruft.
Der Listener ist also eine Implementierung eines Interfaces, die _du_ baust, um dem Produzenten eines Events mitzugeben, was er bitte aufrufen soll, damit _du_ auf das Ereignis _reagieren_ kannst.
Das Ereignis selbst tut nichts. Deine Listener-Implementierung tut was.
Die Adapter-Klassen (also z.B. die aus Swing) sind nur Klassen, die ein Listener-Interface leer implementieren, also bei jeder Methode _nichts_ tun, damit du im Zweifel nicht 10 Methoden des Interfaces implementieren musst, wenn du nur eine davon brauchst - du kannst also stattdessen vom Adapter ableiten und nur eine Methode überschreiben.
Die Methode getSource() auf einem Ereignis gibt die im Falle von z.B. Java Swing das UI Element, welches das Ereignis ausgelöst hat, also z.B. den JButton, auf den geklickt wurde.
 
Man versucht immer, Klassen so unabhängig wie möglich zu halten.

Und mit Hilfe von Abstraktionen kann man hier einiges an Unabhängigkeit erreichen.
Dies erreicht man z.B. über Interfaces. Dir ist egal, was für ein Auto du fährst - es muss aber das Interface AutoMitSchaltgetriebe haben.

Dieser erste Schritt Klassen unabhängig zu machen, reicht aber leider nicht ganz. Das ist super, denn eine Instanz fest auf eine andere zugreifen will. Aber nun kann es sein, dass es weitere Klassen gibt, die noch gar nicht bekannt sind. Wenn das Auto einen Unfall hat, dann soll irgend etwas automatisch passieren. Was genau weiss man aber nicht, wenn man das Auto baut. Das weisst auch Du nicht, der das Auto später baut. Also baut man das einfach als eine universelle Sache ein. Man schafft ein Interface, das für die Benachrichtigung da ist. Und dann darf sich jeder, der an dem Ereignis interessiert ist, anmelden um dann über das Ereignis informiert zu werden.

Nichts anderes ist das mit den Events. Ein Event ist einfach ein Ereignis. In einer Oberfläche kann es sein; Der Anwender hat auf etwas geklickt, hat eine Taste gedrückt oder oder oder ....
Das nennt sich dann Event. Event ist also ein Ereignis.

Ein Listener ist jemand, der dann dem Event interessiert ist. Dieser muss in der Regel ein bestimmtes Interface erfüllen. Halt das Interface, das notwendig ist, um das Event entgegen zu nehmen.

In dem Aufruf gibt es dann natürlich notwendige Daten. Auto baut Unfall -> Da sind dann Daten wichtig, z.B. genaue Koordinaten, welches Auto es war u.s.w. Diese Informationen sind bei jedem Event durchaus unterschiedlich. In einer UI hat ein Event aber einen Ursprung (source). Und diesen Ursprung kann man abfragen. Das kann aber vom Prinzip (fast) alles sein, daher kann hier nur ein universeller Typ genommen werden. Das kann z.B. Object sein. Damit Du mit der Referenz etwas anfangen kannst, musst du natürlich in den eigentlichen Typ zurück gehen. Du machst also ein Cast ist das, was der Ursprung war. Das funktioniert aber natürlich nur, wenn das auch stimmt. Wenn der Ursprung des Events ein MenuItem war und Du willst es nach Button casten: Das geht nicht. Dann bekommst Du eine ClassCastException.
Klar - wenn Ursprung ein Auto ist und Du willst es als Fahrrad nutzen: Das geht nicht.

Bezüglich Adapterklassen ist der Kontext nicht unwichtig. Ich kenne Adapterklassen eigentlich als Klassen, die andere Instanzen umwandeln. Du hast also einen Adapter um Transferobjekte entgegen zu nehmen und deine eigenen Entities auszugeben und umgekehrt.

Aber https://javabeginners.de/Klassen_und_Interfaces/Adapterklassen.php beschreibt auch eine andere Art von Adapterklasse, die ich irgendwie sehr kritisch sehe. Evtl. meinst Du dies. Da geht es um Interfaces mit mehreren Methoden und dann abstrakten Klassen, die das Interface implementieren und die dann statt Interface verwendet werden können. Diese Klassen haben eine leere Methode für jede vom Interface angeforderte Methode und sollen dazu dienen, dass man nicht alle Methoden implementieren muss.
Warum sehe ich das kritisch: Es ist sehr wichtig, sauberen, wartbaren Code zu schreiben, so genannten Clean Code. Und es gibt in dem Bereich sehr viele Überlegungen. Stark duchgesetzt hat sich u.a. "Uncle Bob" (Robert C.Martin - Autor diverers Bücher, hat gute Videos auf Youtube!) der massgeblich an den SOLID Principles beteiligt war. Und ein Principle ist "Interface segregation". Interfaces sollten so klein sein, dass eben diese Notwendigkeit nicht mehr bestehen kann!

Du hast ein Interface I mit den Methoden a und b. Das setzt voraus, dass die Methoden a und b so zusammen hängen, dass diese nicht einzeln Sinn ergeben. Wenn es Sinn machen kann, a und b zu Trennen, dann macht es auch Sinn, das Interface aufzutrennen. Dann hast Du Ia mit a und Ib mit b.

Beispiel:
Eine Ente kann quaken und schwimmen. Jetzt hast Du etwas, das kann nur Schwimmen. Dann ist es aber ggf. keine Ente ... Also macht man lieber zwei Interfaces KannQuaken und KannSchwimmen.
 
Beste Antwort

Zurück
Oben