浅析 接口回调

搞过Android的同志们,尤其是初学者,对于接口回调应该不陌生的,至少应该见过下面的代码:

        //给按钮设置点击事件
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                
            }
        });

OnClickListener就是android系统所预留好的接口,我们写的应用程序中传入回调对象,这样就可以达到接口统一,实现不同的效果。

什么是接口回调?

接口回调是用接口句柄来得到并调用实现这个接口的子类的引用。也可以理解为把实现接口的类的实例的引用赋值给接口变量后,该接口变量就可以回调类重写的接口方法。

听起来有点绕口,举个例子:
在这里插入图片描述Code B想调用Code A中的A(),但是又想A()在执行的过程中调用Code B自身中的CallB(),那么可以定义一个接口IA,IA可以直接调callB(),CodeB实现IA接口,并且重写了里面的callB(),而Code A通过持有接口IA的引用ia,通过ia.callB()调用callB(),只需要Code B在调用Code A中的A()之前,传入实现接口IA的Code B引用。这个过程就是接口回调。

用代码描述这个过程:
IA可以直接调用callB()

public interface IA {
    void callB();
}

CodeA通过持有IA接口的引用,直接调用callB()

public class CodeA {

    private IA ia;
    public void setIa(IA ia) {
        this.ia = ia;
    }

    public void A() {
        System.out.println("i am is A() of CodeA !");
        ia.callB();
        System.out.println("A() is finished !");
    }
}

CodeB实现IA接口,重写callB()

public class CodeB implements IA{

    //在调用CodeA.A()之前,传入实现IA接口的CodeB引用
    public void doA() {
        CodeA codeA = new CodeA();
        codeA.setIa(this);
        codeA.A();
    }

    @Override
    public void callB() {
        System.out.println("i am is callB() of CodeB !");
    }
}

测试:

public class Main {
    public static void main(String[] args) {
        new CodeB().doA();
    }
}

结果输出:

i am is A() of CodeA !
i am is callB() of CodeB !
A() is finished !

接口回调的好处

引用博客https://blog.csdn.net/bjyfb/article/details/10462555

为了使我们写的函数接近完美,就把一部分功能外包给别人,让别人个性化定制,至于别人怎么实现不管,我唯一要做的就是定义好相关接口,这一设计允许了底层代码调用高层定义的子程序,增强程序灵活性,和反射有着异曲同工之妙,这才是回调的真正原因!
上层模块封装时,很难预料下层模块会如何实现,因此,上层模块只需定义好自己需要但不能预料的接口(也就是回调接口),当下层模块调用上层模块时,根据当前需要的实现回调接口,并通过注册或参数方式传入上层模块即可,这样就实现下层调用上层,并且上层还能根据传入的引用来调用下层的具体实现,将程序的灵活性大大的增加了。

猜你喜欢

转载自blog.csdn.net/qq_36270361/article/details/106200340