CallBack(回调函数)

CallBack

CallBack介绍

  CallBack:被称为回调函数,在编程时常常用CallBack或者Cb表示。在一些大型项目中常常会用到,因为回调函数不区分语言,因此把回调函数作为计算机科学的大类里面介绍,因为C++和Python都可以将一个函数作为参数传递到其他函数中,因此回调方法的理解较为简单,这里重点介绍Java语言的回调机制。

CallBack使用场景

小伙伴们可能听说过回调函数,但是没有过多关注这一块内容,等到我们进入了大型工程项目中,这是必不可少的知识体系。

用一个简单的例子入手,比如在家里吃饭,我会告诉妈妈我饿了,然后我的妈妈会调用做饭的方法,然后我怎么知道妈妈做好了呢?这时候就需要妈妈在做好饭的时候来通知我可以吃饭了,这时候,我就可以调用吃饭的方法了。
1

当然小伙伴们会说了,这个没什么实用性呀,那就说一些有实用意义的。比如我们要使用WIFI,我们要先告诉WIFI,等到WIFI连接成功后,调用我们的方法即可。或者一些动效,当动效播放完毕的时候,会自动调用我们的方法,通知我们可以进行下一步操作。

CallBack实现

我们就用这个简单的例子进行实战,看一看使用回调函数的优点体现在哪里。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class Mom {
public String name = "Mom";

public void cook() {
System.out.println(name + " is cooking");
}
}

public class Tom {
public String name = "Tom";
public Mom mom;

Tom(Mom mom) {
this.mom = mom;
}

public void play() {
System.out.println(name + " is playing");
}

public void hungry() {
System.out.println(name + " is hungry");
mom.cook();
}

public void eat() {
System.out.println(name + " is eating");
}
}

public class Test {
public static void main(String[] args) {
Mom mom = new Mom();
Tom tom = new Tom(mom);
tom.play();
tom.hungry();
tom.eat();
}
}

上面的代码是不使用回调函数的方法实现Tom吃饭的代码,运行结果如下。我们看一下问题在哪里?

1
2
3
4
Tom is playing
Tom is hungry
Mom is cooking
Tom is eating

貌似没有什么问题,先产生一个Mom对象,然后Tom对象持有这个mom,当Tom饿了调用mom的cook方法,最后调用Tom的eat方法。

但是我们从时序上面分析,就立刻看出来问题所在,我们如何知道eat方法在什么时候调用呢?如果cook是一个耗时操作,在多线程场景下会不会出现Tom的eat方法在Mom的cook方法之前执行的问题呢?这时候我们使用回调方法进行修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public interface CallBack {
void eat();
}

public class Mom {
public String name = "Mom";

public void cook(CallBack callBack) {
System.out.println(name + " is cooking");
callBack.eat();
}
}

public class Tom {
public String name = "Tom";
public Mom mom;

Tom(Mom mom) {
this.mom = mom;
}

public void play() {
System.out.println(name + " is playing");
}

public void hungry() {
System.out.println(name + " is hungry");
mom.cook(new CallBack() {
@Override
public void eat() {
System.out.println(name + " is eating");
}
});
}
}

public class Test {
public static void main(String[] args) {
Mom mom = new Mom();
Tom tom = new Tom(mom);
tom.play();
tom.hungry();
}
}

首先我们创建一个回调接口CallBack,然后给Mom的cook方法传入一个实现接口的实例,当cook方法结束后,调用该实例的eat方法。然后只需要在Tom中创建一个实现接口的实例即可。

有的小伙伴们就会问了,那为什么不把Tom直接传给Mom呢?直接在Mom的cook方法中调用Tom的eat方法不就可以了吗?

原因是这样做违反了设计模式中接口隔离的原则,一个类对另一个类的依赖,应该建立在最小的接口上。因为Mom不需要使用Tom的其他方法,所以直接将Tom传给Mom是不合理的。

CallBack小结

  CallBack在自己写小Demo中的作用不大,但是在实际的工程项目中会发挥巨大的作用,尤其是Android开发,往往涉及多个线程,多个模块直接的交互,因此软件开发的小伙伴们,一定要掌握回调函数的使用。

-------------本文结束感谢您的阅读-------------
0%