回调

2020-03-10 10:51:41 浏览数 (1)


1. 回调

回调简单而言:在一个类(A)的方法(a)中调用另一个类(B)的方法(b),当方法(b)执行完之后就调用类(A)中的方法(c),这就是回调的过程,是不是很简单?简单分析可以知道一个类(A)持有另一个类(B)的引用,方法(c)就叫做回调函数,画成UML图就如下所示:

2. 同步回调

这里模拟一个情景,小狗邀请小猫出去玩,而小猫要午睡,所以小狗要等到小猫睡醒了才一起出去玩,要实现的功能是小猫睡醒了回调通知小狗

其主要对象有:

  • 回调接口
  • 回调实现类
  • 被调用者

2.1 回调接口

代码语言:javascript复制
public interface Callback {
    
    // 回调函数
    public void callback();

}

2.2 回调实现类

代码语言:javascript复制
public class Dog implements Callback {
    
    // 持有类B的引用
    private Cat cat;
    public void setCat(Cat cat) {
        this.cat = cat;
    }
    
    public void playOutside(){
        System.out.println("Dog:invite cat to play outside,but cat is sleep");
        cat.sleep(this);    // 重点在此,方法参数为回调类
    }
    
    @Override
    public void callback() {
        System.out.println("Dog:Let's go");
    }
    
}

2.3 被调用者

代码语言:javascript复制
public class Cat {
    
    public void sleep(Callback callback){
        System.out.println("Cat:i need to sleep");
        System.out.println("Cat:i am sleeping");
        System.out.println("Cat:i am sleeping");
        System.out.println("Cat:i am waking up");
        callback.callback();  // 在此回调
    }
}

2.4 测试

代码语言:javascript复制
public class test {
    
    public static void main(String[] args) {
        
        Dog dog = new Dog();
        Cat cat = new Cat();
        
        // 设置引用
        dog.setCat(cat);
        
        // 邀请小猫出去玩
        dog.playOutside();
    }
}
代码语言:javascript复制
Dog:invite cat to play outside
Cat:i need to sleep
Cat:i am sleeping
Cat:i am sleeping
Cat:i am waking up
Dog:Let's go

3. 异步回调

回调最重要体现在异步上,在上面的例子中,小狗在等小猫醒来的过程中是被阻塞不能执行其他任务的,所以异步回中小狗在等小猫过程中可以干其他事情,等小猫醒了再去执行出去玩这个任务,提高了执行效率

3.1 改造Dog类

代码语言:javascript复制
public class Dog implements Callback {
    
    private Cat cat;
    public void setCat(Cat cat) {
        this.cat = cat;
    }
    
    public void playOutside(){
        System.out.println("Dog:invite cat to play outside");
        new Thread( () -> {
                try {
                    cat.sleep(this);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
        }).start();
    }
    
    public void watchTV(){
        System.out.println("Dog:i am watching TV");
    }
    
    public void playGame(){
        System.out.println("Dog:i am playing Game");
    }
    
    @Override
    public void callback() {
        System.out.println("Dog:Let's go");
    }
}

3.2 改造Cat类

代码语言:javascript复制
public class Cat {
    
    public void sleep(Callback callback) throws InterruptedException{
        System.out.println("Cat:i need to sleep");
        System.out.println("Cat:i am sleeping");
        System.out.println("Cat:i am sleeping");
        Thread.sleep(5000);     // 猫说完就睡了5秒
        System.out.println("Cat:i am waking up");
        callback.callback();    // 猫醒来就告诉狗
    }
}

3.3 异步回调测试

代码语言:javascript复制
public class test {
    
    public static void main(String[] args) throws InterruptedException {
        
        Dog dog = new Dog();
        Cat cat = new Cat();
        dog.setCat(cat);
        
        // 小狗邀请小猫
        dog.playOutside();
        
        // 这里睡1秒为了让小狗邀请小猫这个动作执行完
        Thread.sleep(1000);
        
        // 小猫午睡期间小狗执行了其他任务
        dog.watchTV();
        dog.playGame();
        
    }
}
代码语言:javascript复制
Dog:invite cat to play outside
Cat:i need to sleep
Cat:i am sleeping
Cat:i am sleeping
Dog:i am watching TV
Dog:i am playing Game
Cat:i am waking up
Dog:Let's go

0 人点赞