zoukankan      html  css  js  c++  java
  • 通过女朋友来通俗易懂讲解“接口回调”,一不小心就被绿

    @

    背景

    最近要接一个数据,小松不知道怎么弄,导师说:你可以定义一个接口回调啊

    然后我就吭哧吭哧的写,写到一半,发现有点不对劲。顿时发现自己的接口回调用少了,只能对付常用的几个场景,。但是一旦在几百万代码的产品中,很多接口回调都是自定义或者用别人的自定义的。

    所以今天,我们就好好的来剖析一下什么是接口回调

    回调

    假设,现在小松有一个女朋友,小鹿,我们在一起生活,要生活呢就要洗碗,如果我和她都学会洗碗,显然,我们内部的代码是重复的,我们都有一个洗碗的方法,这样组成的家庭不好,理论上,只要有一个人会洗碗就够了,另一个人去学别的东西。

    现在小鹿会洗碗了,所以她的方法是这样子

    class littleLu {
        public void washUp(n){
            System.out.println("小鹿洗好了碗");
        }
    }
    

    小松作为一个居家好男人,也不老是让小鹿洗碗啊,但是自己不能去学习洗碗,不然代码就重复了,所以聪明的小松写了一个办法,就是——"执子之手,用来洗碗"
    小松让小鹿改变她的方法,只要把小松传进去,小鹿就会用小松的手来洗碗

    abstract class Person{
        private String name;
        private String hand;
        public String getHand() {
            return hand;
        }
    }
    class LittleLu extends Person{
        private String name="littleLu";
        private String hand="littleLu的手";
        public void washUp(Person person){
            System.out.println(person.getHand()+"洗好了碗");
        }
    }
    

    上面的代码,首先定义一个人的抽象类,只要是人,都有名字还有手,再补一个获得手的public方法,然后小鹿有一个洗碗的方法washUp,只要把人传进去,就可以让这个人的手来洗碗

    怎么做呢?小松将自己当做参数交给小鹿,然后小鹿用她的洗碗方法来洗就可以了(感觉有点奇怪,但是就是这个意思)

    abstract class Person{...}
    class LittleLu extends Person{...}
    public class LittleSong extends Person{
        private String name="littleSong";
        private String hand="littleSong的手";
    
        public String getHand() {
            return hand;
        }
    
        public static void main(String[] args) {
            LittleLu littleLu=new LittleLu();
            LittleSong littleSong = new LittleSong();
            littleLu.washUp(littleSong);
        }
    }
    

    上面的main方法中,小松把自己传入到小鹿的washUp方法里面,小松不需要会洗碗,也能通过小鹿的方法来洗。
    打印结果

    littleSong的手洗好了碗
    

    此时,回调已经产生了

    1. 注意看,在LittleSong这个类的main方法中,new了一个littleLu,并且调用了littleLu的washUp方法,这个是一个调用。
    2. 但是,他在调用的同时也传入了自己,使得washUp方法也可以拿到LittleSong对象,然后调用LittleSong中的getHand()方法将碗给洗了,如果这个步骤单独看,他也是一个调用。

    第一个步骤小松调用了小鹿的方法,第二个步骤小鹿又反过来调用小松的方法

    核心句子是这句:如果不好理解可以再看看上文的例子
    A调用B的方法,传入自己,然后B的方法拿到A后再调用A的方法干事情

    这,就是回调

    回调的最大好处在于,虽然最终做事情的是A,但是中途A需要某些东西,只有B有,就像例子中的虽然需要小松来洗碗,但是小松不会,此时需要小鹿的方法来帮助小松洗碗。

    你可能会问,为什么这么麻烦?小松小鹿都学会洗碗不就好了吗?
    但是,此时只有两个人,假如说,小鹿又找了一个男朋友,那这个男朋友是不是也要学会洗碗呢?如果小鹿有一群男朋友,外加包养几个小鲜肉,岂不是每个人都要学会洗碗?
    所以,有些方法,只能某个类有,虽然真正干事情的是A,但是他不需要会干事情,只要提供自己的东西给会干事情的人干即可

    比如工人不需要会盖房子,只要把自己的力气卖给包工头就行,然后包工头反过来调用他们的力气去盖房子

    接口

    讲到这里可能有些人要喷我了,不是说好的接口回调吗?接口呢?
    这是一个循序渐进的过程,为什么需要接口?因为上面的方法虽然好,但是有很大的安全隐患!!看main方法

    public static void main(String[] args) {
            LittleLu littleLu=new LittleLu();
            LittleSong littleSong = new LittleSong();
            littleLu.washUp(littleSong);
    }
    

    小松只是为了洗个碗,却把自己整个交给了小鹿,小鹿岂不是可以对小松为所欲为?计算机中,给的权限刚好足以,决不能多给,这是非常危险的,比如说littleSong的name就可以比littleLu获取到。

    此时接口就上场了,一个接口,只需要声明一个getHand方法,然后传入到小鹿的washUp方法中的参数,修改为这个接口即可,我们来看看,我们之前都是继承Person的,现在,将Person变成接口,只保留getHand方法

    interface Person{
         String getHand();
    }
    class LittleLu implements Person{
        private String name="littleLu";
        private String hand="littleLu的手";
        public void washUp(Person person){
            System.out.println(person.getHand()+"洗好了碗");
        }
        @Override
        public String getHand() {
            return hand;
        }
    }
    public class LittleSong implements Person{
        private String name="littleSong";
        private String hand="littleSong的手";
    
        @Override
        public String getHand() {
            return hand;
        }
        public static void main(String[] args) {
            LittleLu littleLu=new LittleLu();
            LittleSong littleSong = new LittleSong();
            littleLu.washUp(littleSong);
        }
    }
    

    此时的打印结果依然还是原来的,但是看到了吗?在washUp方法中,传入的是Person,而Person里面,只有一个getHand方法,小鹿只能获得getHand方法,也就是说,就算是阿猫阿狗,只要你实现了Person接口,有了getHand的方法,小鹿也会,并且只会用你的手来洗碗。

    这就是接口回调的核心要义,
    你调用我的方法,然后把你传进去,我的方法在那你调用你的方法干事情
    你为了保护自己,仅仅把你实现的接口部分传进去,我也只看接口部分的东西

    女朋友也是程序员,希望她不要看到这篇文章

  • 相关阅读:
    docker搭建lnmp环境
    通过brew安装docker以及docker的使用
    源码编译安装扩展-phpize详解
    php7废弃mcrypt加密,使用openssl替换
    ubuntu安装docker
    mac 操作系统使用iterm(2)自动登录远程服务器
    linux 用户及用户组管理
    let var const 区别
    ubuntu 升级node和npm 版本
    OLTP与OLAP
  • 原文地址:https://www.cnblogs.com/chen-song/p/13733324.html
Copyright © 2011-2022 走看看