实例讲解回调机制

本文通过具体的代码示例介绍了回调机制的基本概念及其应用场景。首先通过静态回调的例子展示了如何在完成任务后通知另一方,接着通过实例回调的方式说明了回调机制的灵活性,并提到了观察者模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


     回调机制是一个非常有趣的机制,我对于回调的简单理解就像是一种责任委托一样
     回调的简单定义是: F类调用了H类的某个方法c,而H类反过来调用F类的d,d就是回调方法。
     下面先通过第一个简单的静态回调例子来讲解回调,然后对比流行的实例回调:

     该场景是:   假如B向A发送“削苹果”的指令,A需要完成该任务。完成后,A通知B,B将对A的结果做出反应。
    在实现中,可能A完成指令时,B有其他任务,所以我们考虑使用一个线程来实现A的任务。这样B就不能阻塞在A完成任务时。在视线中,我们考虑通过使用回调来实现A对
   B的通知,这样有很大的便利。先看实现:
    代码实现如下:
class CallBackA implements Runnable{
 String command="";
 public CallBackA(String command){
  this.command = command;
  System.out.println("A:收到消息:"+command);
  System.out.println("A: 完成后,我通知B"); 
 };
 
 public void run(){//使用多线程实现A的任务
  
  System.out.println("A: 正在完成");
  try {
   Thread.sleep(1000);
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  System.out.println("A: 已经完成 通知B");
  CallBackB.receive(command+"完成");  
 }
}

public class CallBackB {

 public static void receive ( String message)//A回调B的方法
 {
  System.out.println("B:收到A的完成消息: "+message);
  System.out.println("B:我吃苹果");
 }
 public CallBackB() {
  // TODO Auto-generated constructor stub
 }

 public static void main(String[] args) {
  // TODO Auto-generated method stub
  System.out.println("B: A削苹果给我,我等你完成");
  CallBackA call = new CallBackA ("削苹果");
  new Thread(call).start();
 }
}

   运行结果:
      
        

    在代码实现中,B在向A发送指令后,A开启线程调用run()方法完成任务。并在完成指令后调用了B的静态方法receive(),就是通知了B自己完成了任务。其中A调用B的receive()方法称为回调方法。该实现使用回调实现A通知B的技巧在于不是B采用轮询重复地询问A是否完成任务(就像一个五岁小孩在长途汽车旅行中反复地问"我们到了吗?") 而是让线程A告诉主程序B何时结束。这是通过调用主类中的一个方法实现的。就是回调,这样主程序可以瞪大线程结束期间休息,而且不会占用线程的时间当线程的run()方法接近结束时,要做的最后一件事就是基于结果调用主程序的一个已知方法。不是由主程序询问每个线程来寻求答案,而是每个线程告知主程序答案。

    在该实现中,A调用B的静态方法,所以该实现也是回调静态实现。但是,一般通用的是回调的实例实现,
    使用实例方法带替静态方法进行回调要复杂一些,下面是实例实现的代码
 * 
class CallBackC implements Runnable{
 
 String command;
 CallBackD call;
 public CallBackC(String command, CallBackD call)
 {
  this.command  = command;
  this.call = call;
 };
 
 public void run()
 {
  System.out.println("C: 接受到来自D的指令:"+command);
  System.out.println("C: 正在处理");
  System.out.println("C: 处理完成   将通知D");
  call.receive("削苹果完成");
  
 }
}

public class CallBackD {

 public CallBackD() {
  // TODO Auto-generated constructor stub
 }
 
 public void receive(String result)
 {
  System.out.println("D: 收到来自C的消息: "+result);
  System.out.println("D: 我吃苹果");
 };
     
 public static void main(String[] args) {
  
  System.out.println("B: A削苹果给我,我等你完成");
  
  CallBackD callD = new CallBackD ();
  CallBackC callC = new CallBackC ("削苹果",callD);//将callD传入Callc,用于回调
  
  new Thread(callC).start();      
 }
}
   实例实现回调跟静态不同的是,需要将callD本身传入callC,callC得到了callD的对象后,callC就可以通过callD回调callD的方法。实例回调方法更加灵活
,可以涉及多个线程,对象和类的更复杂的情况。例如如果有多个对象对CallBackC的削成的苹果感兴趣,那个线程可以保存一个回调 的对象列表。特定的对象课一调用Runnable类的方法把自己添加到这个列表中完成注册,表示对削成的苹果感兴趣。当然,每个对象需要声明自己的回调方法,这可以通过定义一个回调接口,那些对象实现就可以了,这种机制就是著名的观察者模式,大家可以自己去研究一下。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值