接口回调

1 理解

编程分为两类:系统编程(库/函数),应用编程(应用/函数)。
一般,库函数会提供 API(接口),拿过来直接用就好,但是有时候为了更加灵活的编程,有些库函数会要求应用先传给它一个函数,好在合适的时候调用,以完成目标任务。这个被传入的,后又被调用的函数,称为回调函数

旅馆提供 叫醒服务,但是要求旅客自己决定叫醒的方法。可以是打客房电话,也可以是派服务员去敲门,睡得死怕耽误事的,还可以要求往自己头上浇盆水。这里,“叫醒”这个行为是旅馆提供的,相当于库函数,但是叫醒的方式是由旅客决定并告诉旅馆的,也就是回调函数。而旅客告诉旅馆怎么叫醒自己的动作,也就是把回调函数传入库函数的动作,称为登记回调函数(to register a callback function) — 这个就是具体连接 旅客和旅馆的函数


老板让员工做事情,做完通知老板,老板根据员工完成的情况做后续安排
员工--->库函数(旅馆)---中间函数:无论是哪个老板,安排什么任务,都是员工做
事情(接口)
老板(旅客)---回调函数
旅客告诉旅馆怎么叫醒自己的动作 —>在回调函数里定义的完成事情的方法

2 具体解析

B实现回调接口,A使用B的引用,因为B本身就是个接口,是让A使用的
A让B做事情

  • 1 接口 首先,事情单独抽象出来,成为一个接口,接口包括,A让B做什么,需要得到什么结果(在参数里定义)

doHomeWork(String question,String answer);
void yes();
void no();

  • 2 B中间函数(本质是个接口,只不过接口的功能自己定义的) B做事情,B是库函数(中间函数),负责提供接口的,把事情做好,作为一个接口(引用),供A调用 —(因为A让B做事情,B就是个接口,A使用B接口,事情就完成了) — 和一般接口不同的是,B接口不是系统提供的,是根据 A提供的接口的引用,自己写的 B的实质就是个接口,B使用接口作为引用,实现A要求的功能,A拿来B(接口)就可以实现想要的功能

getAnswer(String homework,DoHomeWork someone);
doSomething(ProgressOfWork progressOfWork,String event);

  • 3 A(回调函数) 回调函数必须实现回调接口,并且实现登记回调函数,即A让B做事情的完整实现逻辑,就应该定义在A这个回调函数里面, B就是个接口,供A使用的,那A让B做事情,A的方法里一定有 (事情,B的引用)这两个参数
// 在构造函数里初始化B
public Boss(Employee employee) {
    this.employee = employee;
}
// 在方法里得到B做事情的方法,这个在 起始函数里要用,
public void doEvent(String event){
    // 将当前对象传给员工,员工才可以回调   
     employee.doSomething(this,event);
}

 // 用匿名内部类的形式实现B的实例
ask( final String homework, final RoomMate roomMate){ 
     roomMate.getAnswer(homework, Student.this);
}
  • 4 在起始函数里调用

B是一个接口,A让B做事情,那么A函数里一定包含B的引用了,在起始函数里直接调用即可,起始函数不定义具体的方法

3 具体实例
3.1 Boss通知员工做事情,员工完成任务之后告诉Boss完成情况。

1 接口

public interface ProgressOfWork {
    public abstract void yes();
    public abstract void no();
}

2 员工(B,中间函数)

public class Employee {

    public Employee(){}

    // 完成 Boss交代的事情,回调接口作为参数传过来
    public void doSomething(ProgressOfWork progressOfWork,String event){
        String flag = null;
        System.out.println("Employee:doingWork:"+event);

        // 根据完成的情况,通知 Boss,即回调接口
        System.out.println("Employee:finish the work!");
        flag = "finish";
        if(flag.equals("finish")){
            progressOfWork.yes();
        }

        System.out.println("Employee:not finish the work"+event);
        flag="notFinish";
        if(flag.equals("notFinish")){
            progressOfWork.no();
        }

    }

}

3 老板A(回调函数)

// Boss 需要实现 回调的接口
public class Boss implements ProgressOfWork {

    // 传入一个员工对象
    private Employee employee;

    // 构造函数里面进行初始化
    public Boss(Employee employee){
        this.employee = employee;
    }

    // 告诉员工要做什么事情 --- 登记回调方法
    public void doEvent(String event){
        System.out.println("Boss:"+event);
        // 将当前对象传给员工,员工才可以回调
        employee.doSomething(this,event);
    }


    // 员工完成事情后的回调方法
    @Override
    public void yes() {
        System.out.println("Boss:Work Well Doing");
    }

    @Override
    public void no() {
        System.out.println("Boss:not finish work");
    }
}

4 起始函数

public class Test {

    public static void main(String[] args) {
        Employee employee = new Employee();
        Boss boss = new Boss(employee);
        boss.doEvent("write aaaaaaa");
    }

}
3.2 A让室友帮忙做作业 — 使用匿名内部类实现

1 接口

public interface DoHomeWork {
    public abstract void doHomeWork(String question,String answer);
}

2 室友(中间函数,接口)

public class RoomMate {

    public void getAnswer(String homework,DoHomeWork someone){

        if("1+1=?".equals(homework)){
            someone.doHomeWork(homework,"2");
        }else if("当x趋向于0,sin(x)/x=?".equals(homework)){
            System.out.println("思考:");

            for(int i=1;i<=3;i++){
                System.out.println(i+"秒");
                try{
                    TimeUnit.SECONDS.sleep(3);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
            System.out.println("经过思考得出结果:");
            someone.doHomeWork(homework,"1");
        } else{
            someone.doHomeWork(homework,"空白");
        }

    }

}

3 学生(回调函数)

public class Student implements DoHomeWork {

    @Override
    public void doHomeWork(String question, String answer) {
        System.out.println("作业本");
        if(answer !=null){
            System.out.println("作业:"+question+"答案:"+answer);
        }else{
            System.out.println("作业:"+question+"答案:"+"空白");
        }
    }
    
// 具体实现,登记回调函数
    public void ask(final String homework,final RoomMate roomMate){
        new Thread(new Runnable() {
            @Override
            public void run() {
                roomMate.getAnswer(homework,Student.this);
            }
        }).start();
        
        goHome();
    }

    private void goHome() {
        System.out.println("我回家了...好室友,帮我写一下作业");
    }
}

4 起始函数

public class DoWork {
    public static void main(String[] args) {
        Student student = new Student();
        String homewok = "当x趋向于0,sin(x)/x=?";
        student.ask(homewok,new RoomMate());
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值