用Java接口实现回调函数的等价功能

来源:互联网 发布:生煎网络用语的意思 编辑:程序博客网 时间:2024/05/05 10:19

Java接口实现回调函数的等价功能

首先,看一下回调函数的定义及起源:

简而言之,回调函数就是一个通过函数指针调用的函数,如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说是回调函数。

为什么要使用回调函数?

因为可以把调用者与被调用者分开。调用者不关心被调用者,所有它需要知道的,只是存在一个具有某种特定原型,某些限制条件(如返回值为int)的调用函数。

如果想知道回调函数在实际中有什么作用,先假设有一种情况,我们要编写一个库,它提供了某些排序算法的实现,如冒泡排序、快速排序、shell排序、shake排序等等,但为了使库更加通用,不想再函数中嵌入排序逻辑,而让使用者来实现相应的逻辑;或者,想让库可用于多种数据类型(int, float, string),此时,该怎么办呢?可以使用函数指针,并进行回调。回调可用于通信机制,例如,有时要在程序中设置一个计时器,每到一定时间,程序会得到相应的通知,但通知机制的实现者对我们的程序一无所知,而此时,就需有一个特定原型的函数指针,用这个指针来进行回调,来通知我们的程序事件已经发生。

 

Java支持方法指针之前,Java接口不能提供一种实现回调函数的好方法。熟悉MS-WindowsX Window System事件驱动编程模型的开发人员,习惯于传递在某种事件发生时调用( 回调”)的函数指针,Java的面向对象模型目前并不支持方法指针。

Java的接口支持提供一种获得回调的等价功能的机制。其技巧就是:定义一个简单接口,并在该接口中声明我们要调用的方法。

例如:假定我们希望在某个事件发生时得到通知。我们可以定义一个接口:

public interface InterestingEvent {

       // 这仅是一个常规方法。因此如果需要,

       //  它可以有返回值,也可接收参数

       public void interestingEvent();

}

这使得我们可以控制实现该接口类的任何对象。因此,我们不必关心任何外部类型的信息。

public class EventNotifer {

       private InterestingEvent ie;

       private boolean somethingHappened

       public EventNotifer(InterestingEvent event) {

       // 保存事件对象以备后用

       ie = event;

       // 还没有要报告的时间。

}

 

public void doWork() {

       // 检查在别处设置的谓词

       if (somethingHappened) {

       // 通过调用接口的这个方法发出事件信号

       ie.interestingEvent();

}

}

      

}

在上例中,我们使用somethingHappend谓词来跟踪是否触发事件。在许多情况下,调用此方法足以保证向interestingEvent()发出信号。

希望接收事件通知的代码必须实现InterestingEvent接口,并将自身引用传递个事件通知程序。

public class CallMe implements InterestingEvent {

       private EventNotifer en;

       public CallMe() {

       // 创建事情通知程序,并将自身引用传递给它

       en = new EventNotifer(this);

}

 

// 为事件定义实际的处理程序

public void interesting() {

       // 必定发生了感兴趣的事件!

       // 执行某些操作。。。。

}

}

 

当通常大家说的回调函数一般就是按照别人定义好的接口规范写的,等别人调用的函数,在C语言中,回调函数通常通过函数指针来传递:在Java语言中,通常就是编写另外一个类或类库的人定义一个接口,然后你实现这个接口,然后把这个实现类的一个对象作为参数传给别人的程序,别人的程序必要时就会调用哪个接口来调用你编写的函数。

 

原创粉丝点击