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.最后就是单一责任原则了。