我正在尝试区分侦听器和适配器。
它们几乎是一样的但是在监听器中你必须实现接口中的所有方法,但是使用适配器你可以选择只实现你需要的方法,这样代码就是清理器并且更容易阅读?
我也被告知适配器只使用一个实现来启用实例化而你无法实例化监听器,我不完全理解这一点。
有人可以解释哪一个更好用,哪些你可以做一个但你不能用另一个?
答案 0 :(得分:31)
WindowListener interface
会强制您override
所有方法,而WindowAdapter是WindowListener
的实现,您只需要{{1}你想要处理的方法。
override
是接口,意味着您无法实例化WindowListener
,而WindowListener
是具体类,您可以使用WindowAdapter
运算符进行实例化。
当您使用new
时,代码更干净,您的类只会覆盖您想要的方法。
例如:
WindowAdapter
使用适配器时,代码更清晰:
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) {
}
}
或者
// at JFrame class
addWindowListener(new CloseListener());
// reusable Close Listener
public class CloseListener extends WindowAdapter {
@Override
public void windowClosed(WindowEvent e) {
System.exit(0);
}
}
所以我建议使用addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
,但必须遵循。但是,只有WindowAdapter
存在两个相同的API,以便于创建侦听器对象。
编辑:
由于WindowAdapter
是WindowListener
,您可以在JFrame子类中实现它。
interface
但你不能用public class MainWindow extends JFrame implements WindowListener {
// this is ok
}
public class MainWindow extends JFrame, WindowAdapter {
// this is not allow
}
来做。
答案 1 :(得分:8)
你可以用任何一种方法做任何事情,但是如果从界面开始,你的代码就会有很多样板。我确定你注意到了,当你尝试出来的时候。关于实例化等的陈述是一种非常复杂的说法,并且存在很多术语混淆。你可以写
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) { }
});
或者你可以写
c.addWindowListener(new WindowAdapter() {
@Override public void windowClosed(WindowEvent arg0) { System.exit(0); }
});
在任何情况下,您实例化 WindowListener
或WindowAdapter
都不是 - 您正在创建实现WindowListener
/ extend WindowAdapter
的匿名类。但是当你直接实现接口时,你被迫实现所有方法,当你扩展适配器类时,你只能覆盖你需要的东西。该类已经具有您必须在Listener
情况下编写的这些空实现。
答案 2 :(得分:0)
有一些适配器类,例如MouseAdapter,KeyAdapter,WindowAdapter,可以扩展,从而避免编写您不需要的方法。
接口的东西是你必须写出你不需要的所有方法。 Adapter类可以进一步为Sub Classed,作为覆盖所需方法的方法。
答案 3 :(得分:0)
当您计划使用大多数接口方法时,将使用侦听器。当您只需要使用一些方法时,适配器会更好b / c,您不必覆盖剩余的方法。
答案 4 :(得分:0)
还有另一个方面没有在其他答案中解决:API演变。提供适配器类(a.k.a空接口或接口的默认实现)使得在接口中引入新方法不那么痛苦。如果API仅提供接口,则客户端被迫实现它们,如果向接口添加新方法,则所有实现类都将中断。但是,如果提供了默认实现,那么客户端就有机会扩展它们,除了方便之外,它们可以帮助它们升级到更新的API版本。使用{8}的Java 8默认/空实现变得不那么重要了,但它们在旧版本中可能会很方便。