在使用Swing编写一个窗口的时候,经常需要给一个控件加一个监听器,说的通俗点,就是当我们在界面中加一个按钮,想要让它实现对应的功能,就需要给它加一个监听器,当点击按钮的时候,就能完成需要的功能。所以今天我们来简单模拟一下监听器的内部实现过程~~
假定给出一个类(可以理解成一个小小的框架),在这个类中,它可以实现自己原本的功能,对于一些功能,留到将来用户使用的时候,具体去实现。为了这个类的完整性,把这些遗留下的功能,给出一个接口,在将来用户实现的时候,只需要实现给出的接口就可以啦。
比如这个类:↓
package aboutZhenTingZheModel;
public class SomeClass {
private String message;
public SomeClass() {
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
//需要IMyListener的一个对象,可以在外面调用这个方法
public void innerDoSomething(IMyListener listener) {
System.out.println("SomeClass本身完成的内容!");
//这里调用接口中的方法是为了向外面传递message这个参数,当然可以不传递
//这里调用接口中的方法的个数将在之后的Test类中产生影响。
listener.doSomething(message);
listener.doOtherthing(message);
System.out.println("SomeClass本身完成的内容!");
}
}
在这个类中,innerDosomething()的参数是用一个接口定义的对象。哎呦,接口类型,我也是第一次遇到,不过确实有用~~
两个输出就当是实现自己的功能了,将来用户要实现的功能,就是listener调用的两个函数。
而这里的接口,随便给出一个即可。但是注意,SomeClass类中的对象所调用的方法就是接口中定义的方法,你发现了吗。
package aboutZhenTingZheModel;
public interface IMyListener {
void doSomething(String message);
void doOtherthing(String message);
}
实现这个监听器的第一种方法:实例化接口。在实际调用的时候,通过实现接口来完成。需要注意,由于是接口,所以要实现所有的函数。
some.innerDoSomething(new IMyListener(){
@Override
public void doSomething(String message) {
//这里不仅可以使用它本身提供的这个借口,还可以对其内部的message进行操作
System.out.println("doSomething()方法,参数是:" + message);
}
@Override
public void doOtherthing(String message) {
System.out.println("doOyherthing()方法,参数是:" + message);
}
});
第二种方法:用一个适配器先去实现SomeClass类中的所有类,在实际调用中就可以根据自己的选择,覆盖需要的方法。需要注意,没有覆盖的方法,不代表没有使用,而是使用了适配器中实现的方法。
适配器:(就是接口的一个实现类)
package aboutZhenTingZheModel;
public abstract class MyListenerAdapter implements IMyListener {
//其实就是一个实现类
@Override
public void doOtherthing(String message) {
//这里的输出是为了让大家知道,调用过程中,若没有复用这个函数,不代表这个函数不使用。
System.out.println("你好");
}
@Override
public void doSomething(String message) {
}
}
调用类:
some.innerDoSomething(new MyListenerAdapter() {
//这里有选择的覆盖需要的方法,没有覆盖的方法会用实现类中默认的方法(需要注意默认方法不一定是空的)。
@Override
public void doSomething(String message) {
System.out.println("[" + message + "]");
}
});
前面两种方法都是通过匿名内部类实现的。
第三种方法,内部类:直接在函数内部覆盖:
static class AAA extends MyListenerAdapter {
public AAA() {
}
@Override
public void doOtherthing(String message) {
System.out.println("AAA");
}
}
感觉没有讲的很清楚,给出完整代码,大家消化消化:
前面几个完整的代码就不重复啦~~
package aboutZhenTingZheModel;
public class Test {
public static void main(String[] args) {
SomeClass some = new SomeClass();
some.setMessage("abcdefg");
System.out.println("第一种方法(实例化接口):------------------------");
//由于IMyListener是接口,所以在实例化的时候,首先需要实现其内部所有的方法
some.innerDoSomething(new IMyListener(){
@Override
public void doSomething(String message) {
//这里不仅可以使用它本身提供的这个借口,还可以对其内部的message进行操作
System.out.println("doSomething()方法,参数是:" + message);
}
@Override
public void doOtherthing(String message) {
System.out.println("doOyherthing()方法,参数是:" + message);
}
});
System.out.println("第二种方法(实现类,适配器):------------------------");
some.innerDoSomething(new MyListenerAdapter() {
//这里有选择的覆盖需要的方法,没有覆盖的方法会用实现类中默认的方法(需要注意默认方法不一定是空的)。
@Override
public void doSomething(String message) {
System.out.println("[" + message + "]");
}
});
System.out.println("第三种方法(内部类):------------------------");
some.innerDoSomething(new AAA());
}
//因为main方法是static修饰的,所以下面这个方法必须是static修饰的
static class AAA extends MyListenerAdapter {
public AAA() {
}
@Override
public void doOtherthing(String message) {
System.out.println("AAA");
}
}
//前两方法将产生匿名内部类,如第二种,产生的匿名内部类其实是MyListenerAdapter()的子类。
}
大概就是这个样子,若存在问题,一起留言讨论哦~~