内部类大展身手 ———— 内部类提供闭包,实现回调接口

/**
*   内部类大展身手 ———— 内部类提供闭包,实现回调接口:
*
* 回调(Callback):
*
*   将一般回调接口命名为 Callback
*   回调引用命名为 callbackReference
*   包含回调引用的方法命名为 f(Callback callbackReference)
*
* 那么,回调机制最一般过程:
*  1)A类实现回调接口 Callback; A类 –> 被调用方
*  2) B类中有回调引用 callbackReference 和 f B类 –> 回调方
*  3) 在某个时刻,B类的回调引用捕捉 A类 对象,
*     即执行语句 f(new A());
* 然后,通过这个回调引用去调用A类的方法,这个被调用的方法就称为 回调方法
*
* 注:你也可以,在A类中,调用B类的 f,
* 调用语句如下: new B().f(A.this);
* 更一般的情况是:A类 中含有 B类 的引用 b ,所以直接 b.f(A.this);
*
* 下面的例子:
* Incrementable –> 回调接口
* increment() –> 回调方法
*/

interface Incrementable{
    void increment();
}

//简单地实现接口
class Callee1 implements Incrementable{
    private int i = 0;

    public void noCallback(){
        System.out.println("Callee1: Please don't callback me!!!");
    }

    @Override
    public void increment() {
        i++;
        System.out.println("Callee1 i = "+i);
    }
}


class Callee2{
    private int i = 0;

    public void noCallback(){
        System.out.println("Callee2 : Please don't callback me!!!");
    }

    public void increment() {
        i++;
        System.out.println("Callee2 i = "+i);
    }

    /**
     *   这里通过内部类实现回调接口来完成回调机制的好处是:
     * 这里,内部类相当于外部类的一个“窗口”,而透过这个“窗口”,
     * 你只能看到 外部类 的 increment() 方法,这提供了一种安全保证。
     */
    public class Closure implements Incrementable{
        @Override
        public void increment() {
            Callee2.this.increment();
        }
    }

    Incrementable getCallbackReference(){
        return new Closure();
    }
}

class Caller{
    private Incrementable callbackReference;  //回调引用

    Caller(Incrementable callbackReference) {
        this.callbackReference = callbackReference;
    }

    public Incrementable callbackReference() {
        return callbackReference;
    }
}

public class Callbacks {
    public static void main(String[] args) {
        Callee1 c1 = new Callee1();
        Callee2 c2 = new Callee2();

        //Caller 捕捉 Callee 类的引用
        Caller caller1 = new Caller(c1);
        Caller caller2 = new Caller(c2.getCallbackReference());

        //对于 caller1
        caller1.callbackReference().increment();  //这个是允许的
        //通过 回调引用 向下转型访问 noCallback()
        ((Callee1)caller1.callbackReference()).noCallback(); //这个是不允许的,不安全

        caller2.callbackReference().increment();
        //((Callee2)caller2.callbackReference()).noCallback();
        // 错误的转型,内部类基类的引用转型为外部类
        //((Callee2.Closure)caller2.callbackReference()).increment();
        // 若内部类公有,转型也是多余,只能访问 increment().

    }
}

运行结果
这里写图片描述

错误转型
这里写图片描述

  最后,通过以上例子,可以看出 哪个被调用方(Callee) 传递引用 给 回调方(Caller),回调方就调用 那个 被调用方的 方法,这种“动态调用”,类似于多态,这也就是回调机制的灵活性所在。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值