java - ¿Cuál es la diferencia entre oyentes y adaptadores?
swing awt (5)
Hay otro aspecto que no se aborda en otras respuestas: evolución API. Proporcionar clases de adaptadores (también conocidas como implementaciones vacías o predeterminadas de las interfaces) hace que la introducción de nuevos métodos en las interfaces sea menos dolorosa. Si una API solo proporciona interfaces, los clientes se ven obligados a implementarlas y, si se agrega un nuevo método a las interfaces, todas las clases de implementación se romperán. Sin embargo, si se proporcionan implementaciones predeterminadas, los clientes tienen la posibilidad de ampliarlas, lo que, además de ser práctico, les ayuda a actualizar a una versión de API más nueva. Con los métodos predeterminados de Java 8, la implementación predeterminada / vacía se ha vuelto menos importante, pero pueden ser útiles en versiones anteriores.
Estoy tratando de diferenciar entre oyentes y adaptadores.
¿Son prácticamente iguales pero en los oyentes tienes que implementar todos los métodos en la interfaz, pero con los adaptadores tienes la opción de implementar solo los métodos que necesitas para que el código sea más limpio y fácil de leer?
También me dijeron que los adaptadores permiten la creación de instancias con una sola implementación y que no se pueden crear instancias de oyentes. No entiendo completamente esto.
¿Puede alguien explicar cuál es mejor usar y qué cosas puedes hacer con una pero no con la otra?
Hay varias clases de adaptadores como MouseAdapter, KeyAdapter, WindowAdapter que se pueden extender y así evitar escribir los métodos que no necesita actualmente.
Lo que ocurre con las interfaces es que debes escribir todos los métodos que no necesitas. La clase de Adaptador puede ser Subclasificada como una forma de anular el método requerido.
Los oyentes se utilizan cuando planea utilizar la mayoría de los métodos de interfaz. Cuando necesite utilizar solo algunos de los métodos, un adaptador sería mejor b / c; no tendría que anular el resto de los métodos.
Puedes hacer todo con cualquiera de ellas, pero si comienzas con la interfaz, tu código tendrá MUCHAS palabras. Estoy seguro de que lo notaste cuando lo probaste. Esa afirmación sobre ejemplificación, etc., es una forma bastante complicada de decirlo y hay mucha confusión de términos. Puedes escribir
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) { }
});
o puedes escribir
c.addWindowListener(new WindowAdapter() {
@Override public void windowClosed(WindowEvent arg0) { System.exit(0); }
});
En ninguno de los casos está creando instancias de WindowListener
o WindowAdapter
está creando clases anónimas que implementan WindowListener
/ extend WindowAdapter
. Pero cuando implementa la interfaz directamente, se ve obligado a implementar todos los métodos, mientras que cuando amplíe la clase de adaptador, solo puede anular lo que necesita. Esa clase ya tiene exactamente estas implementaciones vacías que tuvo que escribir en el caso Listener
.
WindowListener es una interface
que te obliga a override
todos los métodos, mientras que WindowAdapter es la implementación de WindowListener
y solo tienes que override
los métodos que te interesan.
WindowListener
es una interfaz que significa que no se puede crear una instancia del WindowListener
, mientras que WindowAdapter
es una clase concreta que puede usar un new
operador para la creación de instancias.
Cuando usa WindowAdapter
, el código es más limpio donde su clase solo anula el (los) método (s) que desea. Por ejemplo:
WindowListener
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) {
}
}
WindowAdapter
Mientras usa el adaptador, el código es más limpio:
// at JFrame class
addWindowListener(new CloseListener());
// reusable Close Listener
public class CloseListener extends WindowAdapter {
@Override
public void windowClosed(WindowEvent e) {
System.exit(0);
}
}
O
addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
Así que recomendaría usar WindowAdapter
, pero no debe seguir . Sin embargo, dos de las API sobre el mismo solo que WindowAdapter
existe como conveniencia para crear objetos de escucha.
EDITAR:
Como WindowListener
es una interface
, puede implementarlo en su subclase JFrame.
public class MainWindow extends JFrame implements WindowListener {
// this is ok
}
public class MainWindow extends JFrame, WindowAdapter {
// this is not allow
}
Pero no puedes hacerlo con WindowAdapter
.