再谈java回调函数

 更新时间:2015年07月29日 10:25:02   转载 投稿:hebedich  
个人对于回调函数的理解就是回调函数就是回头再调用的函数,哈哈,下面我们来详细探讨下回调函数。

又遇到了回调函数,这次打算写下来分享一下。

所谓回调函数,或者在面向对象语言里叫回调方法,简单点讲,就是回头在某个时间(事件发生)被调用的函数。

再详细点:就是一个函数A,作为参数,传入了另一个函数B,然后被B在某个时间调用。

这里可以有疑问了,既然是一个函数调用另一个函数,可以在函数体里面调用啊,为什么还要把函数作为参数传到另一个函数里被调用?何况还有一些语言(比如java)不支持把函数作为参数。

对的,确实可以在函数体里调用另一个函数,功能上好像是没差别的,但是这里有一个问题,就是你要调用的这个函数被写死了,也就是说这样函数B只能调用函数A了,这样如果在另一个情景下,有个与A不同实现的函数C也需要在B的某个时刻被调用,那怎么办。

下面继续说回调函数,在c/c++里,回调函数可以使用函数指针作为参数被另一个函数调用;在c#里,可以使用委托,如果是事件方法的话,还有event关键字;在python和javascript里,可以直接把函数当对象传参,这些语言都很好实现回调函数(方法),可是, java呢? 先说点题外话,自从学了C#,就不喜欢java了,曾经一度打算以后不再用java,可是现实并没有那么理想,我现在要做android,所以还是不能放下java,而且今天遇到这个回调函数的问题,也是从java里遇到的,我个人觉得,在这个博客里出现的语言,除了java外,对于回调,都可以既容易,又好理解的实现,但是java,我觉得并不是那样,不然我也不会来写这篇博客。

好了继续说,关于java中的回调方法的实现。这篇博客的重点就是说java的。 在java中,回调方法是用借用接口来实现的,我在网上找到一句话:

“把实现某一接口的类所创建的对象的引用,赋值给该接口声明的接口变量,那么该接口变量就可以调用被实现的接口的方法”。
很绕哈,简单解释下:
有一个接口,接口里有一个方法(这个方法就是要回调的方法):

interface CallBackInterface {
  void callBackMethod();
}

我们知道,接口对象不能直接用,因为里面的方法都没有实现。所以要找个类实现这个接口。
所以现在加一个类,实现这个接口:

interface CallBackInterface {
  void callBackMethod();
}

class CallBackClass implements CallBackInterface{

  @Override
  public void callBackMethod() {
    System.out.println("hello");
  }
}

好了,最后一步:把实现了接口的类的对象赋值给声明的接口变量(我给写进一个方法里了,然后外面加了个类的壳子):

public class CallBackTest {

  interface CallBackInterface {
    void callBackMethod();
  }

  class CallBackClass implements CallBackInterface {

    @Override
    public void callBackMethod() {
      System.out.println("hello");
    }
  }

  public void showCallBack() {
    CallBackInterface itfs = new CallBackClass();
    itfs.callBackMethod();
  }
}

现在可以调用试试看了:

public class Test {
  public static void main(String[] args) {
    new CallBackTest().showCallBack();
  }
}

没意外的话,会成功输出hello,反正我这边是的.

例子看完了,所以说我做了什么呢? 再详细点说,我们有一个要在某一个方法里被调用的方法(这个方法就是回调方法), 前面我们也说了,最好不要直接把想要回调方法做的事直接写在调用方法里, 又因为java里没法把方法当做参数传递,所以我们只好把这个回调方法放在了接口里(为什么不是类?不是抽象类?而是接口?你可以自己去找下抽象类与接口的异同,自己解决这个问题)。有接口的话,就要被类实现,然后,只要是给接口的对象赋予实现类的对象,这个接口的对象就可以调用那个方法了。理解这里的话,有一个重点,就是多态, 这里用到的多态知识就是,接口的对象可以顺利被子类赋值,并且调用子类的重写方法(类也有类似的概念)。

再多说一点,这里任何实现了CallbackInterface接口的类,都可以像下面这样放在new后面(就是赋值):

public class CallBackTest {
  interface CallBackInterface {
    void callBackMethod();
  }

  class CallBackClass implements CallBackInterface {

    @Override
    public void callBackMethod() {
      System.out.println("hello");
    }
  }

  class Controller {
    private CallBackInterface cbitf;
    // 这个boolean只是为了模拟有事件,没啥实用价值
    public boolean somethingHappend;
    // 这里确实可以直接把CallBackClass做参数,而且省掉接口的定义
    // 但是这样做的话,就像是回调函数直接写在了调用函数里一样
    // 不明白的话就好好理解下"约定"和"调用者不管回调函数是怎么实现的"吧
    public Controller(CallBackInterface itfs) {
      somethingHappend = true;
      this.cbitf = itfs;
    }

    public void doSomething() {
      if(somethingHappend) {
        cbitf.callBackMethod();
      }
    }
  }

  public void showCallBack() {
    CallBackClass cbc = new CallBackClass();
    Controller ctrlr = new Controller(cbc);
    ctrlr.doSomething();
    // 其实上面也可以这样写在一行里
    // new Controller(new CallBackClass()).doSomething();
  }
}

最后多说一点,其实这种应用在android里会经常遇到,我就是在学android的时候遇到的。

以上就是个人对于回调函数的理解和使用方法了,希望大家能够喜欢。

相关文章

  • Mybatis传list参数调用oracle存储过程的解决方法

    Mybatis传list参数调用oracle存储过程的解决方法

    怎么利用MyBatis传List类型参数到数据库存储过程中实现批量插入数据?接下来通过本文给大家介绍Mybatis传list参数调用oracle存储过程,需要的朋友可以参考下
    2017-03-03
  • mybatis的插件机制示例详解

    mybatis的插件机制示例详解

    这篇文章主要给大家介绍了关于mybatis插件机制的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用mybatis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-06-06
  • 详解Java8 新特性之日期API

    详解Java8 新特性之日期API

    Java 8 在包java.time下包含了一组全新的时间日期API。下面通过示例给大家讲解java8 新特征日期api的相关知识,感兴趣的朋友一起看看吧
    2017-07-07
  • 详解Spring Data操作Redis数据库

    详解Spring Data操作Redis数据库

    Redis是一种NOSQL数据库,Key-Value形式对数据进行存储,其中数据可以以内存形式存在,也可以持久化到文件系统。Spring data对Redis进行了很好的封装,用起来也是十分的得心应手,接下来通过本文给大家分享Spring Data操作Redis数据库,需要的朋友参考下
    2017-03-03
  • 简单的java图片处理类(图片水印 图片缩放)

    简单的java图片处理类(图片水印 图片缩放)

    本图片处理类功能非常之强大可以实现几乎所有WEB开发中对图像的处理功能都集成了,包括有缩放图像、切割图像、图像类型转换、彩色转黑白、文字水印、图片水印等功能
    2013-11-11
  • IntelliJ IDEA创建maven web项目的图文步骤(IDEA新手适用)

    IntelliJ IDEA创建maven web项目的图文步骤(IDEA新手适用)

    这篇文章主要介绍了IntelliJ IDEA创建maven web项目的图文步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • java Spring整合Freemarker的详细步骤

    java Spring整合Freemarker的详细步骤

    本文对Spring整合Freemarker步骤做了详细的说明,按步骤操作一定可以整合通过,这里提供给大家做参考
    2013-11-11
  • mybatis快速入门学习教程新手注意问题小结

    mybatis快速入门学习教程新手注意问题小结

    MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。接下来通过本文给大家介绍mybatis快速入门学习教程新手注意问题小结,需要的朋友可以参考下
    2017-02-02
  • 详解Spring Cloud中Hystrix的请求合并

    详解Spring Cloud中Hystrix的请求合并

    这篇文章主要介绍了详解Spring Cloud中Hystrix的请求合并,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • Java使用路径通配符加载Resource与profiles配置使用详解

    Java使用路径通配符加载Resource与profiles配置使用详解

    这篇文章主要介绍了Java使用路径通配符加载Resource与profiles配置使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06

最新评论