实在抱歉啊排版有问题现在已经重写:
地址:
回调概念
"回调,回调"到底是个啥呢?
通过以前的学习知道的是在事件驱动设计模式情况下,回调就是将一个方法的指针传递给事件源
当某一事件发生的时候就调用该方法,这个过程就称为回调,调用的方法就称为回调方法了。
不过我们知道的是java面向对象的程序设计并不支持方法指针,似乎难以实现?不过仔细想想就
可以其实就可以知道java可以使用接口这一技术来实现相同的回调嘛。
接口回调
java中接口回调其实现技巧就是定义一个简单的接口,并在接口中声明我们需要调用的方法。当某
一事件发生的时候我们就通过实现这个接口的方法进行回调,接口的这个方法也就是回调方法了。
只是说明很难让人理解,看看具体如何去实现吧!
接口回调简单实现
其实这在前一篇关于“匿名内部类”的思考中java接口回调就有使用过。
首先编写一个接口,并声明一些需要回调的方法
package com.kiritor; /**@author Kiritor * 事件接口*/ interface EventListener { void clicked(); void pressed(); /*其他的就不多写了*/ }这里有时候接口的方法过多的话在使用内部类实现调用的时候会存在不便,因此编写一个
Adapter进行“适配”。
package com.kiritor; /** * @author Kiritor 事件监听的适配器 */ public class EventAdapter implements EventListener { @Override public void clicked() { // TODO Auto-generated method stub } public void pressed() { }; }
编写一个按钮类,它有添加监听的方法,也就是对按钮的状态改变的进行监听
并执行相关的动作!
package com.kiritor; /** * @author Kiritor 一个按钮 */ public class MyButton { private int flag = 0;// 0代表点击,1代表按下 public MyButton(int flag) { this.flag = flag; } //对按钮添加监听 public void addListener(EventListener eventListener) { if (flag == 0) { eventListener.clicked(); } else eventListener.pressed(); } }看一看测试类:
package com.kiritor; public class Test { public static void main(String[] args) { MyButton button = new MyButton(1); //对按钮添加监听,采用的是Adapter的模式 button.addListener(new EventAdapter() { @Override public void clicked() { // TODO Auto-generated method stub System.out.println("按钮被点击了"); } @Override public void pressed() { // TODO Auto-generated method stub System.out.println("按钮被按下了"); } }); } }上述代码基本上实现了java中awt的相同功能,只是说按钮状态的监听是人为的,因为
按钮状态的改变时底层才知道的。
仔细阅读上述代码部分,我们来看看java中是怎么通过接口进行回调的!
首先看看EventListener接口,不用多说那一定是定义了需要回调的方法。
其次是EventAdapter这个实现了EventListener,在这里没有太过苛刻的要求,读者也可以
不实现它。(其实这算一种设计模式,就不多说了)
接下来就是按钮了MyButton,这里面主要的是方法
//对按钮添加监听 public void addListener(EventListener eventListener) { if (flag == 0) { eventListener.clicked(); } else eventListener.pressed(); }
这里要结合测试类来看,如下
button.addListener(new EventAdapter() { @Override public void clicked() { // TODO Auto-generated method stub System.out.println("按钮被点击了"); } @Override public void pressed() { // TODO Auto-generated method stub System.out.println("按钮被按下了"); } });
new 出来一个按钮并对其添加监听,形成一个匿名内部类对象传递给EventListener接口
由其回调相应的接口方法。该匿名内部类可以有选择的实现需要的方法,这也是为什么
不直接使用EventListener接口的原因。我们知道java中是动态绑定的,最后调用的方法,也
就是匿名内部类中重新实现的方法。
因此结果输出为:按钮被按下了
重新理解回调
通过创建匿名类,动态实现了接口的回调方法,侧重点在于接口,虽说使用的是
EventAdapter但是阅读器源码可以知道,我们并未对其做太多的事情,他只是一种"辅助“
手段!我们真正在意的是重新实现的方法,这个方法是提供个外部实现并由接口回调的。
通俗的来讲就是:我提供给你一个接口的方法交给Coder实现,coder实现过后却由接口
进行回调。 Coder并不能就行直接调用。