2011-03-27 56 views
11

是否有任何好處或缺點創建一個實現ActionListener的一個嵌套類:嵌套類VS工具的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){ 
     //... 
    } 
} 

我見過這兩個例子都很常見,只是想知道是否有'最佳實踐'。

+0

另請參見[嵌套類的優點](http://stackoverflow.com/questions/5085157)。 – trashgod 2011-03-27 18:09:10

回答

3

如果Foo類除了封裝這個按鈕沒有別的責任,那麼第一個解決方案就好了。

但是,只要Foo得到更多的「東西」,它必須聽,然後它變得混亂。我更喜歡第二種解決方案,因爲它更加明確並具有更好的可擴展性。

一個更好的解決方案可能是創建一個匿名的內部類。

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

我認爲第一種方法更好,因爲您的類將有一個單獨的代碼來處理操作。而且通常組合也比繼承更好,所以一個類應該擴展一個類或者實現一個接口,只要它真的是一個超類型的接口。

同樣爲了可維護性,讓我們說Foo類有一個新的需求來偵聽另一個不同類型的事件,然後執行動作,在這種情況下,也可以很容易地修改第一類。

如果我不擔心可維護性,我寧願去一個匿名課程。

+0

請看答覆作爲答案 – 2011-03-27 18:26:20

3

通常你想使用嵌套或者甚至匿名的類,而不是將ActionListener暴露給封閉類的API。 (公共類Foo實現ActionListener - > Javadoc將聲明Foo是一個ActionListener,雖然這通常只是一個實現細節 - >不好)

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