Ich versuche zwischen Listenern und Adaptern zu unterscheiden.
Sind sie ziemlich gleich, aber in Listenern müssen Sie alle Methoden in der Schnittstelle implementieren, aber mit Adaptern haben Sie die Möglichkeit, nur die Methoden zu implementieren, die Sie benötigen, damit der Code übersichtlicher und einfacher zu lesen ist?
Mir wurde auch gesagt, dass Adapter die Instantiierung mit nur einer Implementierung ermöglichen und dass Sie keine Listener instantiieren können. Ich verstehe das nicht ganz.
Kann jemand bitte erklären, welches besser zu gebrauchen ist und was man mit dem einen machen kann, aber nicht mit dem anderen?
WindowListener ist interface
, was Sie zwingt, alle Methoden zu override
zu zwingen, während WindowAdapter die Implementierung von WindowListener
ist und Sie nur die override
-Methode (en) benötigen, die Sie behandeln möchten.
WindowListener
ist eine Schnittstelle, die bedeutet, dass Sie die WindowListener
nicht instantiieren können, während WindowAdapter
eine konkrete Klasse ist, die Sie mit dem new
-Operator zur Instantiierung verwenden können.
Wenn Sie WindowAdapter
verwenden, ist der Code sauberer, wobei Ihre Klasse nur die Methoden überschreibt, die Sie möchten. Zum Beispiel:
public class CloseListener implements WindowListener {
// im not interest on this event, but still need to override it
@Override
public void windowOpened(WindowEvent e) {
}
// im not interest on this event, but still need to override it
@Override
public void windowClosing(WindowEvent e) {
}
@Override
public void windowClosed(WindowEvent e) {
System.exit(0);
}
// im not interest on this event, but still need to override it
@Override
public void windowIconified(WindowEvent e) {
}
// im not interest on this event, but still need to override it
@Override
public void windowDeiconified(WindowEvent e) {
}
}
Während der Verwendung des Adapters ist der Code sauberer:
// at JFrame class
addWindowListener(new CloseListener());
// reusable Close Listener
public class CloseListener extends WindowAdapter {
@Override
public void windowClosed(WindowEvent e) {
System.exit(0);
}
}
Oder
addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
Ich würde also empfehlen, WindowAdapter
zu verwenden, aber nicht muss folgen . Es gibt jedoch zwei APIs, die WindowAdapter
ähnlich sind, um Listener-Objekte zu erstellen.
BEARBEITEN:
Da WindowListener
interface
ist, können Sie es in Ihrer JFrame-Unterklasse implementieren.
public class MainWindow extends JFrame implements WindowListener {
// this is ok
}
public class MainWindow extends JFrame, WindowAdapter {
// this is not allow
}
Aber du kannst es nicht mit WindowAdapter
.
Sie können alles mit einem von beiden machen, aber wenn Sie mit der Schnittstelle beginnen, wird Ihr Code eine Menge Boilerplate haben. Ich bin mir sicher, dass Sie das bemerkt haben, als Sie es ausprobiert haben. Diese Aussage über Instantiierung usw. ist eine ziemlich komplizierte Art zu sagen, und es gibt viel Verwirrung der Begriffe. Du kannst schreiben
c.addWindowListener(new WindowListener() {
@Override public void windowActivated(WindowEvent arg0) { }
@Override public void windowClosed(WindowEvent arg0) { System.exit(0); }
@Override public void windowClosing(WindowEvent arg0) { }
@Override public void windowDeactivated(WindowEvent arg0) { }
@Override public void windowDeiconified(WindowEvent arg0) { }
@Override public void windowIconified(WindowEvent arg0) { }
@Override public void windowOpened(WindowEvent arg0) { }
});
oder du kannst schreiben
c.addWindowListener(new WindowAdapter() {
@Override public void windowClosed(WindowEvent arg0) { System.exit(0); }
});
In keinem Fall erstellen Sie instanziiert entweder WindowListener
oder WindowAdapter
— Sie erstellen anonyme Klassen, die WindowListener
/erweitern WindowAdapter
implementieren. Wenn Sie die Schnittstelle direkt implementieren, müssen Sie jedoch alle Methoden implementieren. Wenn Sie die Adapterklasse erweitern, können Sie nur das überschreiben, was Sie benötigen. Diese Klasse hat bereits genau diese leeren Implementierungen, die Sie im Fall Listener
schreiben mussten.
Ein anderer Aspekt wird in anderen Antworten nicht angesprochen: API-Evolution. Durch die Bereitstellung von Adapterklassen (a.k.a leere oder Standardimplementierungen von Schnittstellen) ist die Einführung neuer Methoden in Schnittstellen weniger schmerzhaft. Wenn eine API nur Schnittstellen bereitstellt, müssen die Clients diese implementieren, und wenn eine neue Methode zu den Schnittstellen hinzugefügt wird, werden alle implementierenden Klassen beschädigt. Wenn jedoch Standardimplementierungen bereitgestellt werden, haben die Clients die Möglichkeit, diese stattdessen zu erweitern. Dies ist nicht nur praktisch, sondern hilft ihnen auch beim Upgrade auf eine neuere API-Version. Mit Standardmethoden von Java 8 ist die standardmäßige/leere Implementierung weniger wichtig geworden, sie kann jedoch in älteren Versionen hilfreich sein.
Es gibt verschiedene Adapterklassen wie MouseAdapter, KeyAdapter, WindowAdapter, die Sie erweitern können, um das Schreiben der Methoden zu vermeiden, die Sie nicht wirklich benötigen.
Bei Schnittstellen müssen Sie alle Methoden ausschreiben, die Sie nicht benötigen. Die Adapter-Klasse kann außerdem als Unterklasse bezeichnet werden, um die erforderliche Methode zu überschreiben.
Listener werden verwendet, wenn Sie die meisten Schnittstellenmethoden verwenden möchten. Wenn Sie nur einige der Methoden verwenden müssen, wäre ein Adapter besser, wenn Sie den Rest der Methoden nicht überschreiben müssen.