嵌套类vs实现ActionListener

创建实现ActionListener的嵌套类是否有任何好处或缺点:

public class Foo{ Foo(){ something.addActionListener(new ButtonListener()); } //... private class ButtonListener implements ActionListener{ public void actionPerformed(ActionEvent e){ //... } } } 

与在主类本身中实现ActionListener相比:

 public class Foo implements ActionListener{ Foo(){ something.addActionListener(this); } //... public void actionPerformed(ActionEvent e){ //... } } 

我经常看到这两个例子,只是想知道是否有“最佳实践”。

@Ankur,您仍然可以使用匿名内部类作为您的侦听器,并且拥有一个独立的独立控件类,因此具有相当可维护的代码,这是一种我喜欢使用的技术。 例如:

 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class AnonymousInnerEg { private static void createAndShowUI() { GuiPanel guiPanel = new GuiPanel(); GuiControl guiControl = new GuiControl(); guiPanel.setGuiControl(guiControl); JFrame frame = new JFrame("AnonymousInnerEg"); frame.getContentPane().add(guiPanel); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static void main(String[] args) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { createAndShowUI(); } }); } } class GuiPanel extends JPanel { private GuiControl control; public GuiPanel() { JButton startButton = new JButton("Start"); startButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (control != null) { control.startButtonActionPerformed(e); } } }); JButton endButton = new JButton("End"); endButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (control != null) { control.endButtonActionPerformed(e); } } }); add(startButton); add(endButton); } public void setGuiControl(GuiControl control) { this.control = control; } } class GuiControl { public void startButtonActionPerformed(ActionEvent ae) { System.out.println("start button pushed"); } public void endButtonActionPerformed(ActionEvent ae) { System.out.println("end button pushed"); } } 

我认为第一种方法更好,因为您的类将有一个单独的代码来处理操作。 通常组合也比inheritance更好,所以一个类应该扩展一个类或实现一个接口,只要它真的是一个超类型。

同样为了可维护性,让我们说Foo类有一个新的要求,即侦听另一种不同类型的事件,然后执行操作,在这种情况下,也可以轻松修改第一类。

如果我不担心可维护性,我宁愿去匿名课。

如果Foo类没有其他责任而不是封装这个按钮,那么第一个解决方案就没问题了。

然而,一旦Foo得到更多的“事情”,它必须听,然后它变得混乱。 我更喜欢第二种解决方案,因为它更明确,并且具有更好的可扩展性。

更好的解决方案可能是创建一个不合理的内部类。

 public class Foo{ Foo(){ something.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ //... } }); } } 

通常,您希望使用嵌套甚至匿名类,而不是将ActionListener暴露给封闭类的API。 (公共类Foo实现了ActionListener – > Javadoc将声明Foo是一个ActionListener,虽然这通常只是一个实现细节 – >坏)