A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 我是楠楠 于 2018-4-14 15:16 编辑

【郑州校区】java接口回调的经典使用案例

内容简介:
  • 接口回调的理解及需要关注的问题
  • 接口回调一般常规用法
  • 接口回调简洁用法
  • 接口回调的意义

接口回调简介:
   简单的说接口回调就是:调用者A类访问了被调用者B类中的M方法.这个M方法在执行完毕后又调用了A类中的方法.
问题?
   B类中的M方法是如何访问A类中的方法的呢?弄清了这个问题,也就明白了接口回调.
下面我们根据一个场景描述去编写代码:
   我们在调用者Caller类中使用被调用者Collee类中的下载文件方法DownLoadFile().下载完成后要通知Caller类文件加载完成.这个时候Caller类才能去访问刚才下载的资源.由于下载需要时间.而Caller类还有其他事情要做.不能等着下载完成后再去做.这样的话下载的方法必须开启新的线程去下载.
接口回调一般常规用法
代码实现:1.接口和回调方法:
[AppleScript] 纯文本查看 复制代码
/*
CallBackListener (回调监听接口)
用于回调的接口 (接口内的抽象方法用于监听被调用者返回的结果)
接口中有回调方:该回调方法是被调用者通过回调接口对象去访问调用者的方法.所以形参应该是被调用者返回给调用者结果的数据类型和参数个数。
*/
public interface CallBackListener {
        //发送消息给调用者
        public abstract void sendMessage2Caller(String msg);
}
2.调用者类:
[AppleScript] 纯文本查看 复制代码
/*
Caller :(调用者)
调用者在访问被调用者的方法前.必须将回调接口对象设置给被调用者.以方便被调用者使用接口回调对象访问自己.
*/
public class Caller {
        public static void main(String[] args) {
                //1.创建被调用者对象
                Callee callee = new Callee();
                
                //2.创建回调接口对象.
                CallBackListener cb = new CallBackListener() {
                        
                        @Override
                        public void sendMessage2Caller(String msg) {
                                //打印回调传递过来的结果
                                System.out.println(msg);
                                
                        }
                };
                
                //3.必须将回调接口对象设置给被调用者
                callee.setCallBackListener(cb);
                
                //4.访问被调用者的下载文件方法.这个方法完成后被调用者会通过回调接口对象通知我们.
                callee.DownLoadFile();
                
                System.out.println("你下载真慢,我先去忙别的事了....");
        }
}
3.被调用者类
[AppleScript] 纯文本查看 复制代码
/*
Callee(被调用者):
1.被调用者类中必须有回调接口类型的变量.
2.并且还要有给该变量赋值的setXxx()方法.
3.在可以给调用者返回结果的时候.拿着接口类型的变量调用接口的方法进行对调用者的访问.(因为接口类型的变量要执行的方法在调用者那里存在).
*/
public class Callee {
        //1.被调用者类中必须有 回调接口类型的变量.
        private CallBackListener cb;
        
        //2.并且还要有给该变量赋值的setXxx()方法.
        public void setCallBackListener(CallBackListener cb){
                this.cb = cb;
        }
        
        /**
        * 下载文件是非常耗时的工作.而调用者又需要在下载完成后读取下载的文件.
        * 所以当这个方法完成下载后应该立刻通知调用者.这个通知的动作就称之为回调.
        * @throws InterruptedException 
        */
        public void DownLoadFile(){
                //开启新的线程去下载.异步任务.
                new Thread(){
                        public void run() {
                                long start = System.currentTimeMillis();
                                
                                //使用睡眠模拟耗时工作.
                                try {
                                        Thread.sleep(5000);
                                } catch (InterruptedException e) {
                                        e.printStackTrace();
                                }
                                
                                long end = System.currentTimeMillis();
                                
                                //完成下载后通知调用者
                                if(cb != null){
                                        cb.sendMessage2Caller("下载完成,耗时:"+(end-start)/1000+"秒,你可以去访问资源了.");
                                }
                        };
                }.start();
        }
}
运行结果如下:
5秒钟后
接口回调简洁用法
代码实现:
1.接口和回调方法:
[AppleScript] 纯文本查看 复制代码
/*
CallBackListener (回调监听接口)
用于回调的接口 (接口内的抽象方法用于监听被调用者返回的结果)
接口中有回调方:该回调方法是被调用者通过回调接口对象去访问调用者的方法.所以形参应该是被调用者返回给调用者结果的数据类型和参数个数。
*/
public interface CallBackListener {
        //发送消息给调用者
        public abstract void sendMessage2Caller(String msg);
}
2.调用者类:
[AppleScript] 纯文本查看 复制代码
public class Caller {
        public static void main(String[] args) {
                //1.创建被调用者对象
                Callee callee = new Callee();
                //2.访问被调用者的下载文件方法.这个方法完成后被调用者会通过回调接口对象通知我们.
                //使用匿名内部类对象当做参数传递.更加简洁
                callee.DownLoadFile(new CallBackListener() {
                
                        @Override
                        public void sendMessage2Caller(String msg) {
                                //打印回调传递过来的结果
                                System.out.println(msg);
                        }
                });
                
                System.out.println("你下载真慢,我先去忙别的事了....");
        }
}
3.被调用者类
[AppleScript] 纯文本查看 复制代码
/**
* 下载文件是非常耗时的工作.而调用者又需要在下载完成后读取下载的文件.
* 所以当这个方法完成下载后应该立刻通知调用者.这个通知的动作就称之为回调.
* final CallBackListener cb 匿名内部类访问局部变量必须加final.
*/                
public class Callee {
        public void DownLoadFile(final CallBackListener cb){
                //开启新的线程去下载.异步任务.
                new Thread(){
                        public void run() {
                                long start = System.currentTimeMillis();
                                
                                //使用睡眠模拟耗时工作.
                                try {
                                        Thread.sleep(5000);
                                } catch (InterruptedException e) {
                                        e.printStackTrace();
                                }
                                
                                long end = System.currentTimeMillis();
                                
                                //完成下载后通知调用者
                                if(cb != null){
                                        cb.sendMessage2Caller("下载完成,耗时:"+(end-start)/1000+"秒,你可以去访问资源了.");
                                }
                                
                        };
                }.start();
        }
}
接口回调的意义:
通过以上两个案例大家会不会有一个疑问.为什么要搞一个接口呢?把接口换成普通的类可以吗?当然是可以的.这里之所以使用接口回调.是因为接口具有规范性和灵活性.特别是规范性.
代码举例:
1.原来的接口换成抽象类其他两个类不变, 不会影响运行效果
[AppleScript] 纯文本查看 复制代码
public abstract class CallBackListener {
        //发送消息给调用者
        public abstract void sendMessage2Caller(String msg);
}
2.原来的接口换成类其他两个类不变, 不会影响运行效果
[AppleScript] 纯文本查看 复制代码
public class CallBackListener {
        //发送消息给调用者
        public void sendMessage2Caller(String msg){
                
        };
}
传智播客·黑马程序员郑州校区地址
河南省郑州市 高新区长椿路11号大学科技园(西区)东门8号楼三层
联系电话 0371-56061160/61/62
来校路线  地铁一号线梧桐街站A口出

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马