java 嵌套类 vs 实现 ActionListener

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5451010/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 11:11:31  来源:igfitidea点击:

Nested class vs implements ActionListener

javaswingactionlistener

提问by aheuertz

Are there any benefits or drawbacks to creating a nested class that implements ActionListener:

创建实现 ActionListener 的嵌套类有什么好处或缺点:

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

versus implementing ActionListener in the main class itself:

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

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

I've seen both examples quite often, and just want to know if there's a 'best practice.'

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

回答by Hovercraft Full Of Eels

@Ankur, you can still use anonymous inner classes as your listeners and have a separate free-standing control class and thus have code that's quite maintainable, a technique I like to use a bit. For example:

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

回答by Ankur

I think first approach is better, as your class will have a separate code for handling action. And usually also composition is better than inheritance so a class should extend a class or implement a interface only if it truly is-a super type.

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

Also for maintainability, let us say Foo class has a new requirement to listen for another different type of events and then perform action, in that case also first class can be easily modified.

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

If I am not worried about maintainability I would rather go for a anonymous class.

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

回答by Puce

Usually you want to use a nested or even anonymous class rather than exposing ActionListener to the API of the enclosing class. (public class Foo implements ActionListener -> Javadoc will state that Foo is an ActionListener, though this is usually just an implementation detail -> bad)

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

回答by sstendal

If the class Foo has no other responsibility than encapsulating this button, then the first solution is sort of ok.

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

However, as soon as Foo gets more "somethings" that it has to listen to then it gets messy. I prefer the second solution since it is more explicit and has a better scalability.

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

An even better solution may be to create an anomymous inner class.

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

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