嵌套类 vs 实现 ActionListener

11

创建实现 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){
        //...
    }
}

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


请参阅嵌套类的优点 - trashgod
4个回答

10

@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");
   }
}

5

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

此外,考虑到可维护性,假设Foo类需要监听另一种不同类型的事件并执行操作,那么第一种方法也可以很容易地进行修改。

如果我不担心可维护性,我会选择匿名类。


请查看回复以获取翻译后的文本。 - Hovercraft Full Of Eels

3
如果类Foo除了封装这个按钮之外没有其他的职责,那么第一种解决方案还算可以。但是,一旦Foo需要监听更多的"东西",就会变得混乱。我更喜欢第二种解决方案,因为它更明确,而且可扩展性更好。甚至更好的解决方案可能是创建一个匿名内部类。
public class Foo{
    Foo(){
        something.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e){
                //...
            }
        });
    }
}

3

通常情况下,您应该使用嵌套类甚至匿名类,而不是将ActionListener暴露给封装类的API。(public class Foo implements ActionListener -> Javadoc会说明Foo是一个ActionListener,但这通常只是实现细节 -> 不好)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接