你的位置:首页 > Java教程

[Java教程]笑谈接口回调


  接口回调是个比较抽象但是很重要的知识,大多数初学者都会在刚接触它时感觉抓不住要领,但当我们实际掌握它后,会对它爱不释手。废话不多说,让我们开始吧。
  我认识新事物的一般有这样的习惯,就是先从事物的名称入手。那么对于接口回调这个新事物,我们能从这个名字中获取多少信息呢?首先是接口,什么是接口呢?相信有一定编程基础的朋友都知道,就是一种规范,但是这种规范在没有实现之前,没有任何作用。就好比招聘广告一样,广告上列出的条件都是宽泛的,如我要招一名熟悉Java的程序员。这是一个规范,你想来应聘就必须满足熟悉Java这个条件,但满足这个条件的人情况可能千差万别,可能是男的,也可以有女的,可能是高手,也可能刚好满足这个条件。但是只要满足这个条件了,都可以来应聘,都可以称为一名应聘者。这里,招聘条件就是接口,应聘者就是实现。那么回调又怎样理解呢?回调——回来调用,回哪呢,回到定义的地方,回到实现的地方,那么这是不是间接的陈述了一个事实,就是我实现接口的地方和我调用接口的地方不是同一个地方。由此问题是不是就明了了。接口回调就是我有一个功能,但是这个功能我没有,但是有一个实体它有这个功能,我就可以通过它的功能来实现我的功能。
  是不是还很晕呢?是的,那我们接着往下。举一个例子,在文档编辑器中一般会有打印这个功能,我调用打印这个功能的时候,假如不给它提供一台可正常工作的打印机时,它是没有办法工作的。但是当我们接上打印机后,再执行打印这个功能,打印内容出现在了打印机的出口,打印功能完成。可是如果我没有在文档编辑器中调用这个打印功能呢,是不是就不会有打印结果产生了,这是不是很神奇。这就是接口回调的魅力,功能我有但是真正做事的不是我,但是你想做事又不能没有我。
  那么这样做有什么意义呢?再举个例子,如我需要粉刷房子,但是我自己又不会粉刷,那么怎么办呢?肯定得找人来粉刷啊,而不是由粉刷工人来问我是不是需要粉刷房子。因为粉刷的时间是不确定的,不可能每时每刻都有粉刷需求。在我们根据各种情况判断后,在合适的时间,我们再请粉刷工人来完成我们的粉刷任务。在我们不需要粉刷的时候,粉刷工人可以为其他人服务,这样提高了粉刷工人的工作效率,又不至于影响我的粉刷任务。所以接口回调的意义就很明确了,由我来指挥我要做什么事,但是我不做事,我们由执行者的身份转换为了指挥者,这样便于组织我们的功能,又不会浪费一大把的宝贵资源。
  说了老半天,那么我们应该怎样来实现接口回调呢?以上面的粉刷房子为例,我写了一个小的测试程序。

1 package andy.example;2 3 public interface Paint {4   //粉刷任务5   void paint();6 }

在这里,我们定义了一个接口,该接口里只有一个粉刷的方法。

 1 package andy.example; 2  3 //工人实体,具有粉刷功能 4 public class Worker implements Paint{ 5  6   @Override 7   public void paint() { 8     System.out.println("我是一名粉刷匠,粉刷本领强!"); 9   }10 11 }

真正具有粉刷功能的粉刷工人。

 1 package andy.example; 2  3 //可能需要粉刷房子的实体 4 public class Asker { 5  6   // 是否需要粉刷 7   private boolean isNeedPaint; 8  9   public void setIsNeedPaint(boolean isNeedPaint) {10     this.isNeedPaint = isNeedPaint;11   }12 13   /**14    * 指挥粉刷15    * 16    * @param worker17    *      粉刷工人18   */19   public void doPaint(Paint paint) {20     if (isNeedPaint) {21       paint.paint();22     } else {23       System.out.println("房子不需要粉刷,你特么逗我呢!");24     }25   }26 }

可能需要粉刷的人。

 1 package andy.example; 2  3 //测试类 4 public class Test { 5  6   public static void main(String[] args) { 7     //有两个请求者 8     Asker asker1=new Asker(); 9     Asker asker2=new Asker();10     11     //第二个真正需要粉刷12     asker2.setIsNeedPaint(true);13     14     //同一个粉刷工人15     Worker worker=new Worker();16     17     System.out.println("不需要粉刷房子的请求者,调用粉刷方法后");18     asker1.doPaint(worker);19     System.out.println("需要粉刷房子的请求者,调用粉刷方法后");20     asker2.doPaint(worker);21   }22 23 }

测试类。

毫无疑问的结果。

简单分析:需要粉刷的人根据情况判断房子是否需要粉刷,在不需要粉刷的时候调用粉刷功能是无效的,如结果一,真正需要粉刷的人,在合适的时候调用粉刷方法,完成粉刷工作。