關於應該實現ActionListener介面還是使用ActionListener的匿名類物件

茶木君發表於2018-11-14

  java Swing的元件可以產生各種各樣的事件來響應使用者的動作。而java Swing正是通過ActionListener介面接收操作事件並處理操作事件從而反饋給使用者的。
  昨天上java課,聽到老師講解ActionListener介面時,老師特別強調:“儘量建立一個類去實現ActionListener介面,不要使用ActionListener的匿名類物件。”為什麼呢?為什麼需要這樣做?
  關於這樣的問題,首先順向思考,如果定義一個類去實現ActionListener介面,將是這樣的:

    import java.awt.*;
    import javax.swing.*;
    import java.awt.event.*;
    //測試類
    public class Q07{
        public static void main(String args[]){
            new MyWindow();
        }
    }
    //自定義MyWindow類繼承JFrame類
    class MyWindow extends JFrame{
        //序列版本號
        private static final long serialVersionUID = 1L;
        //宣告元件JTextField
        JTextField text;
        //宣告自定義監聽物件
        PoliceStation police; 
        //構造方法完成對物件的初始化操作
        MyWindow(){
            //通過setLayout方法設定此容器的佈局管理器,它是居中對齊的,
            //預設的水平和垂直間隙是 5個單位。
            setLayout(new FlowLayout());
            //例項化JTextField物件,指定文字框首選寬度為10
            text=new JTextField(10);
            //例項化自定義監聽物件
            police=new PoliceStation();
            //將JTextField物件新增至當前視窗
            add(text);
            //使用自定義監聽物件  給JTextField物件新增監聽
            text.addActionListener(police);
            //設定位置和大小
            setBounds(100,100,260,150);
            setVisible(true);
            validate();
            setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        }
    }
    //自定義PoliceStation類實現ActionListener介面
    //老師不建議使用匿名內部類
    class PoliceStation implements ActionListener {
        //實現ActionListener介面中的抽象方法
        //引數:元件動作事件
        public void actionPerformed(ActionEvent e){
            //通過getActionCommand方法返回與此動作相關的命令字串
            String str=e.getActionCommand();
            System.out.println(str);
            System.out.println(str.length()); 
        }
    }

  接下來是使用ActionListener的匿名類:

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
//測試類
public class Q07{
    public static void main(String args[]){
        new MyWindow();
    }
}
//自定義MyWindow類繼承JFrame類
class MyWindow extends JFrame{
	//序列版本號
    private static final long serialVersionUID = 1L;
    //宣告元件JTextField
    JTextField text;
    //構造方法完成對物件的初始化操作
    MyWindow(){
    	//通過setLayout方法設定此容器的佈局管理器,它是居中對齊的,
        //預設的水平和垂直間隙是 5個單位。
        setLayout(new FlowLayout());
        //例項化JTextField物件,指定文字框首選寬度為10
        text=new JTextField(10);
        //將JTextField物件新增至當前視窗
        add(text);
        //使用匿名監聽物件  給JTextField物件新增監聽
        text.addActionListener(new ActionListener() {
			@Override
			//實現ActionListener介面中的抽象方法
			//引數:元件動作事件
		    public void actionPerformed(ActionEvent e){
		    	//通過getActionCommand方法返回與此動作相關的命令字串
		        String str=e.getActionCommand();
		        System.out.println(str);
		        System.out.println(str.length());
		    }
		});
        //設定位置和大小
        setBounds(100,100,260,150);
        setVisible(true);
        validate();
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    }
}

  分析:首先我們發現兩種方法在程式當中的位置就有差別,對於使用自定義類實現了ActionListener介面這一方式而言,它使得監聽模組在程式當中作為一個獨立的部分,並且可以與主類分離,這樣就使程式顯得更加物件導向。然而在使用匿名類時卻不能很好地達到這一點,如果使用匿名類的話,在小程式中看不出什麼,但是當程式複雜起來,功能多起來時,每當我們要設定一個動作時,就要實現一次監聽。假如有100個動作,無論該動作是否存在,都要使用100個匿名類來實現。這樣不僅看起來複雜,實現部分的程式碼與主方法中的程式碼混合在一起,可讀性非常低,而且不符合物件導向的程式設計原則。
  其次,也是最重要的一點,使用匿名類顯然違背了單一責任原則,這是相當糟糕的。
  由此可見,使用自定義類來實現ActionListener介面是更好的方法,理由如下:
1.從程式碼的可讀性上來看,這種方法使得程式更加模組化,自然比匿名類方法的可讀性要好。
2.使用該方法,在新增動作模組時不必再次實現監聽動作的部分,而是直接通過自定義類使用已有的,省去了很多時間。定義動作程式碼部分由自定義類去實現,如果要新增功能,直接在自定義類中新增即可,非常利於程式擴充套件。
3.最後就是單一責任原則了。

相關文章