Java 侦听器和适配器之间有什么区别?
我试图区分侦听器和适配器 它们是否几乎相同,但在侦听器中,您必须实现接口中的所有方法,但使用适配器,您可以选择仅实现所需的方法,以便代码更干净、更易于阅读 我还听说适配器只支持一个实现的实例化,而您不能实例化侦听器,我不完全理解这一点 有人能解释一下哪一个更好用,以及你可以用其中一个做但不能用另一个做的事情吗?是Java 侦听器和适配器之间有什么区别?,java,swing,awt,adapter,listeners,Java,Swing,Awt,Adapter,Listeners,我试图区分侦听器和适配器 它们是否几乎相同,但在侦听器中,您必须实现接口中的所有方法,但使用适配器,您可以选择仅实现所需的方法,以便代码更干净、更易于阅读 我还听说适配器只支持一个实现的实例化,而您不能实例化侦听器,我不完全理解这一点 有人能解释一下哪一个更好用,以及你可以用其中一个做但不能用另一个做的事情吗?是接口,它迫使你覆盖所有的方法,而WindowListener的实现则是覆盖方法你有兴趣处理的 WindowListener是一个接口,这意味着您不能实例化WindowListener,而
接口
,它迫使你覆盖所有的方法,而WindowListener的实现则是覆盖
方法你有兴趣处理的
WindowListener
是一个接口,这意味着您不能实例化WindowListener
,而WindowAdapter
是一个具体的类,您可以使用new
操作符来实例化
当您使用WindowAdapter
时,当您的类只重写您想要的方法时,代码会更干净。
例如:
窗口事件
窗口适配器
使用适配器时,代码更清晰:
// at JFrame class
addWindowListener(new CloseListener());
// reusable Close Listener
public class CloseListener extends WindowAdapter {
@Override
public void windowClosed(WindowEvent e) {
System.exit(0);
}
}
或
因此,我建议使用WindowAdapter
,但不要使用,必须遵循。但是,其中两个API与WindowAdapter
大致相同,只是为了方便创建侦听器对象
编辑:
由于WindowListener
是interface
,您可以在JFrame子类中实现它
public class MainWindow extends JFrame implements WindowListener {
// this is ok
}
public class MainWindow extends JFrame, WindowAdapter {
// this is not allow
}
但是你不能用WindowAdapter
做这一切,但是如果你从界面开始,你的代码将会有很多样板文件。我肯定你在尝试时注意到了这一点。关于实例化等的陈述是一种非常复杂的表达方式,术语上有很多混淆。你可以写
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
/extendWindowAdapter
的匿名类。但是,当您直接实现接口时,您必须实现所有方法,而当您扩展适配器类时,您只能覆盖您需要的。该类已经有了您必须在Listener
案例中编写的空实现。有几个适配器类,例如MouseAdapter、KeyAdapter、WindowAdapter,可以扩展它们,从而避免编写您不需要的方法
接口的问题是,您必须写出所有不需要的方法。适配器类可以进一步细分为子类,以覆盖所需的方法
当您计划使用大多数接口方法时,将使用侦听器。当您只需要使用其中的几个方法时,适配器会更好,b/c您不必重写其余的方法。还有另一个方面,其他答案中没有提到:API进化。提供适配器类(即接口的空或默认实现)可以减少在接口中引入新方法的痛苦。如果API只提供接口,那么客户端将被迫实现它们,如果向接口添加新方法,那么所有实现类都将中断。但是,如果提供了默认实现,那么客户机就有机会扩展这些实现,这除了方便之外,还可以帮助他们升级到新的API版本。随着Java 8的出现,默认/空实现变得不那么重要了,但在旧版本中可能会很方便。谢谢。你介意让我知道“适配器只启用一个实现的实例化,而你不能实例化侦听器”是什么意思吗侦听器接口通常只是一个接口,所以你不能创建一个新的侦听器,你需要为实现这个接口的某个类创建一个新的实例。另一方面,适配器可以直接实例化(如果它们不是抽象的话)——但默认情况下它们通常不做任何事情,因此没有创建它们的实际用例。这是一个非常好的答案。我仍然不明白为什么要实例化适配器类。这项工作何时完成的示例将非常有用。:)如果您正在重用适配器/侦听器来注册到多个对象,这可能是有意义的。例如,您可以使用一个只刷新某些内容的KeyAdapter
。您希望在几个jtextfield上出现这种行为。。。然后您可以创建一个实例,并将该实例添加到所有实例中,而不是创建多个匿名版本。虽然我也不太清楚Pau Kiat Wee的话是什么意思……但我认为您的第二个代码示例的意思是创建WindowAdapter
的实例,而不是WindowListener
,这是唯一澄清我对差异理解的答案!非常感谢你!
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); }
});