因为在看Android代码的时候发现了许多关于回调函数的知识, 所以去了解了一下. 对于我来说不太好懂, 因为我觉得看的那些博文的讲法对我来说很绕, 所以我在理解了之后想写一篇关于回调函数的博文来给和我一样理解能力稍差的人一点帮助.
回调函数的作用其实就是将需要这个功能的调用者与实现这个功能的被调用者分离.
因为可以把调用者与被调用者分开,所以调用者不关心谁是被调用者。它只需知道存在一个具有特定原型和限制条件的被调用函数。
简而言之,回调函数就是允许用户把需要调用的方法的指针作为参数传递给一个函数,以便该函数在处理相似事件的时候可以灵活的使用不同的方法。
用我自己的理解简单来说,
1. 我创建了一个类需要用到一个功能(方法)
2. 于是我先创建该功能的接口
3. 但是我不想自己实现这个功能, 而是想通过调用许许多多的实现该接口的类来完成, 这样的话遇到不同的需求我就可以调用满足该需求的类来实现, 更加的方便
4. 于是我创建了许许多多的类来实现该接口的功能,且每个类中的实现过程都不一样.
5. 那么我如何调用实现方法的类呢? 我将接口作为方法的参数, 这样就可以接受所有实现接口的类了(其实传入的是类的地址), 然后在方法中调用需要的功能方法即可.
从别的博文摘的几句话:
把一段可执行的代码像参数传递那样传给其他代码,而这段代码会在某个时刻被调用执行,这就叫做回调
既然函数指针变量是一个变量,当然也可以作为某个函数的参数来使用的。
// 接口
package cn.ncepu.demo1.a02callbackdemo;
public interface Insert {
public abstract void act();
}
// 实现接口1号
package cn.ncepu.demo1.a02callbackdemo;
public class Isused implements Insert{
@Override
public void act() {
System.out.println("被调用者1号");
}
}
// 实现接口2号
package cn.ncepu.demo1.a02callbackdemo;
public class Isused2 implements Insert{
@Override
public void act() {
System.out.println("被调用者2号");
}
}
// 调用者
package cn.ncepu.demo1.a02callbackdemo;
public class Use {
// 第一种方式
public Use(){
System.out.println("调用者空参构造");
};
public void use(Insert insert){
insert.act();
}
// 第二种方式
// 可以声明成员属性为接口
Insert insert;
public Use(Insert insert){
System.out.println("调用者直接将接口作为参数");
this.insert = insert;
}
public void use2(){
insert.act();
}
}
// 测试
package cn.ncepu.demo1.a02callbackdemo;
public class Test {
public static void main(String[] args) {
Use u = new Use();
final int Isused1 = 0;
final int Isused2 = 1;
final int CODE;
CODE = Isused1;
switch (CODE) {
// 调用第一个实现接口的类的方法
case Isused1 -> u.use(new Isused());
// 调用第二个实现接口的类的方法
case Isused2 -> u.use(new Isused2());
}
}
}
用一段话来总结下回调:上层模块封装时,很难预料下层模块会如何实现,因此,上层模块只需定义好自己需要但不能预料的接口(也就是回调接口),当下层模块调用上层模块时,根据当前需要的实现回调接口,并通过注册或参数方式传入上层模块即可,这样就实现下层调用上层,并且上层还能根据传入的引用来调用下层的具体实现,将程序的灵活性大大的增加了。
package cn.ncepu.demo1.a02callbackdemo2;
public class A {
public void setOnMethodListener(MethodListener methodListener){
methodListener.method();
}
public interface MethodListener{
public abstract void method();
}
}
package cn.ncepu.demo1.a02callbackdemo2;
public class B implements A.MethodListener {
@Override
public void method() {
System.out.println("B类实现A类中的接口");
}
}
package cn.ncepu.demo1.a02callbackdemo2;
public class Test {
public static void main(String[] args) {
A a = new A();
// 直接写(new一个接口的匿名实现类)
a.setOnMethodListener(new A.MethodListener() {
@Override
public void method() {
System.out.println("直接写");
}
});
// 调用类B
B b = new B();
// B类实现A类中的接口的方法
a.setOnMethodListener(b);// 输出:B类实现A类中的接口
}
}
参考博文 :
Java接口回调机制 - 温布利往事 - 博客园 (cnblogs.com)
C语言回调函数详解(全网最全)_小熊coder的博客-CSDN博客_c语言回调函数