【问题标题】:Nested class vs implements ActionListener嵌套类与实现 ActionListener
【发布时间】:2011-03-27 17:42:07
【问题描述】:

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

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

【问题讨论】:

标签: java swing actionlistener


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    我认为第一种方法更好,因为您的班级将有一个单独的代码来处理动作。而且通常组合也比继承好,所以一个类应该扩展一个类或实现一个接口,如果它真的是一个超类型。

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

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

    【讨论】:

    • 请看回复
    【解决方案3】:

    如果类 Foo 除了封装这个按钮没有其他职责,那么第一个解决方案是可以的。

    但是,一旦 Foo 获得了更多它必须听的“东西”,它就会变得一团糟。我更喜欢第二种解决方案,因为它更明确并且具有更好的可扩展性。

    更好的解决方案可能是创建一个异常的内部类。

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-04
        • 2016-10-29
        • 1970-01-01
        • 2016-08-22
        • 1970-01-01
        相关资源
        最近更新 更多