java回调

转载请注意文章出处:https://blog.csdn.net/fengye454545/article/details/80198446

有一段时间没写博客了,可能是因为懒了吧。前几天公司面试有问道java回调的问题,因为这方面也没有太多研究,所以回答的含糊不清,这回特意来补习一下。看了看网上的回调解释和例子,都那么的绕口,得看半天才能绕回来,其实吧,回调是个很简单的机制。在这里我用简单的语言先来解释一下:假设有两个类,分别是A和B,在A中有一个方法a(),B中有一个方法b();在A里面调用B中的方法b(),而方法b()中调用了方法a(),这样子就同时实现了b()和a()两个方法的功能。

疑惑:为啥这么麻烦,我直接在类A中的B.b()方法下调用a()方法就行了呗。
解答:回调更像是一个约定,就是如果我调用了b()方法,那么就必须要回调,而不需要显示调用

一、Java的回调-浅

我们用例子来解释:小明和小李相约一起去吃早饭,但是小李起的有点晚要先洗漱,等小李洗漱完成后,通知小明再一起去吃饭。小明就是类A,小李就是类B。一起去吃饭这个事件就是方法a(),小李去洗漱就是方法b()。


   
   
  1. public class XiaoMing {
  2. //小明和小李一起吃饭
  3. public void eatFood() {
  4. XiaoLi xl = new XiaoLi();
  5. //A调用B的方法
  6. xl.washFace();
  7. }
  8. public void eat() {
  9. System.out.print( "小明和小李一起去吃大龙虾");
  10. }
  11. }

那么怎么让小李洗漱完后在通知小明一起去吃饭呢


   
   
  1. public class XiaoMing {
  2. //小明和小李一起吃饭
  3. public void eatFood() {
  4. XiaoLi xl = new XiaoLi();
  5. //A调用B的方法
  6. xl.washFace();
  7. eat();
  8. }
  9. public void eat() {
  10. System.out.print( "小明和小李一起去吃大龙虾");
  11. }
  12. }

不过上面已经说过了这个不是回调函数,所以不能这样子,正确的方式如下


   
   
  1. public class XiaoLi{ //小李
  2. public void washFace() {
  3. System.out.print( "小李要洗漱");
  4. XiaoMing xm = new XiaoMing();
  5. //B调用A的方法
  6. xm.eat(); //洗漱完后,一起去吃饭
  7. }
  8. }

这样子就可以实现washFace()同时也能实现eat()。小李洗漱完后,再通知小明一起去吃饭,这就是回调。

二、Java的回调-中

可是细心的伙伴可能会发现,小李的代码完全写死了,这样子的场合可能适用和小明一起去吃饭,可是假如小李洗漱完不吃饭了,想和小王上网去,这样子就不适用了。其实上面是伪代码,仅仅是帮助大家理解的,真正情况下是需要利用接口来设置回调的。现在我们继续用小明和小李去吃饭的例子来讲讲接口是如何使用的。

小明和小李相约一起去吃早饭,但是小李起的有点晚要先洗漱,等小李洗漱完成后,通知小明再一起去吃饭。小明就是类A,小李就是类B。不同的是我们新建一个吃饭的接口EatRice,接口中有个抽象方法eat()。在小明中调用这个接口,并实现eat();小李声明这个接口对象,并且调用这个接口的抽象方法。这里可能有点绕口,不过没关系,看看例子就很清楚了。

EatRice接口:


   
   
  1. public interface EatRice {
  2. public void eat(String food);
  3. }

小明:


   
   
  1. public class XiaoMing implements EatRice{ //小明
  2. //小明和小李一起吃饭
  3. public void eatFood() {
  4. XiaoLi xl = new XiaoLi();
  5. //A调用B的方法
  6. xl.washFace( "大龙虾", this); //this指的是小明这个类实现的EatRice接口
  7. }
  8. @Override
  9. public void eat(String food) {
  10. // TODO Auto-generated method stub
  11. System.out.println( "小明和小李一起去吃" + food);
  12. }
  13. }

小李:


   
   
  1. public class XiaoLi{ //小李
  2. public void washFace(String food,EatRice er) {
  3. System.out.println( "小李要洗漱");
  4. //B调用了A的方法
  5. er.eat(food);
  6. }
  7. }

测试Demo:


   
   
  1. public class demo {
  2. public static void main(String args[]) {
  3. XiaoMing xm = new XiaoMing();
  4. xm.eatFood();
  5. }
  6. }

测试结果:

这样子就通过接口的形式实现了软编码。通过接口的形式我可以实现小李洗漱完后,和小王一起去上网。代码如下


   
   
  1. public class XiaoWang implements EatRice{ //小王
  2. //小王和小李一起去上网
  3. public void eatFood() {
  4. XiaoLi xl = new XiaoLi();
  5. //A调用B的方法
  6. xl.washFace( "轻舞飞扬上网", this);
  7. }
  8. @Override
  9. public void eat(String bar) {
  10. // TODO Auto-generated method stub
  11. System.out.println( "小王和小李一起去" + bar);
  12. }
  13. }

测试结果:

三、Java的回调-深

上面讲的都是同步回调,可是事实上,小李要洗漱后才能吃饭,在小李洗漱的时候,小明是要做自己的事情的,比如他在玩手机,这样子就是异步回调了。而且我们把代码正规化,比如在android点击事件中,你会发现你只要实现View.setOnclickListener(this),即可实现回调,那么像这样子的规范是如何实现的,在这一节里我将会提到。废话少说,先上代码。

EatRice接口没有变化,这里就省去接口代码展示

小明:


   
   
  1. public class XiaoMing implements EatRice{
  2. //小明和小李一起吃饭
  3. public void eatFood() {
  4. XiaoLi xl = new XiaoLi();
  5. //A调用B的方法
  6. xl.setEatRiceListener( this, "大龙虾");
  7. }
  8. @Override
  9. public void eat(String food) {
  10. // TODO Auto-generated method stub
  11. System.out.print( "小明和小李一起去吃" + food);
  12. }
  13. }

小李:


   
   
  1. public class XiaoLi{ //小李
  2. protected EatRice er;
  3. public void setEatRiceListener(EatRice er, String food) {
  4. this.er = er;
  5. washFace(food);
  6. }
  7. public void washFace(String food) {
  8. System.out.print( "小李要洗漱");
  9. new Thread( new Runnable() {
  10. @Override
  11. public void run() {
  12. // TODO Auto-generated method stub
  13. try {
  14. //小李洗漱的同时小明玩手机,开启线程实现异步
  15. play();
  16. Thread.sleep( 10000);
  17. System.out.print( "10秒后 ");
  18. //B调用A的方法
  19. er.eat(food);
  20. } catch (InterruptedException e) {
  21. // TODO Auto-generated catch block
  22. e.printStackTrace();
  23. }
  24. }
  25. }).start();
  26. }
  27. //小明玩手机
  28. public void play() {
  29. System.out.println( " 小明要玩手机");
  30. }
  31. }

测试结果:

首先先打印出 "小李要洗漱 小明要玩手机",过了10秒后打印出“10秒后 小明和小李一起去吃大龙虾”。看到这里相信你对Java的回调有了新的认识吧。


菜鸟一只,如有不对之处请指出。您的鼓励是我写作的最大动力!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值