一、什么是回调函数咧?
我的理解:回调函数就是预留给系统调用的函数,而且我们往往知道该函数被调用的时机。这里有两点需要注意:第一点,我们写回调函数不是给自己调用的,而是准备给系统在将来某一时刻调用的;第二点,我们应该知道系统在什么情形下会调用我们写的回调函数;第三点,调用的时候只需要传进对应的参数,就能得到结果。
二、什么时候用回调咧?
第一种情况:你要提供一个处理方法给别人用,但是不想把你的处理方法过多地暴露给别人知道的时候。换句话说,你要求我处理你的需求,但是我不想告诉你,我是怎么实现的时候。 这个时候我提供一个方法,你调用就好了(回调发生在你调用之后,我的实现过程中,而不是调用那一刻就开始)。
第二种情况:写好了处理逻辑,在需要的时候通过调用一个预留的入口来获得想要的结果的时候。
三、打个比喻
你可以把整个回调的过程看成:客人到便利店买水,便利店把从厂家那里拿到的水卖给客户,最后客人就得到了他要的水了。(回调发生在便利店和厂家之间)
下面会写一个输入英文字母 输出全部大写字母 的回调过程
1、首先要写出大写转换处理的逻辑
Handle.java
public class Handle {
public void change(String str, Skills skills)
{
String result = str.toUpperCase();
skills.feedback(str, result);
//这里先接收到数据,然后就是处理获得的数据了
//skills.feedback这句的意思相当于让Skills这个接口里面的feedback获得str和转换后的result(后面Customer的doIt方法是继承于Skills接口的 所以间接地让doIt方法里面的feedback的参数有值)
}
}
2、然后写一个接口,就是调用这个接口来实现功能的
Skills.java
public interface Skills {
public void feedback(String str, String result);
}
3、写一个实体(这里想不到怎么命名 所以用Customer吧)
Customer.java
public class Customer {
public class doIt implements Skills
{
public void call (String str)
{
//提供给调用者用的call方法,这样就避免暴露了处理逻辑,而且让调用更加方便
new Handle().change(str, new doIt());
}
public void feedback(String str, String result)
{
//从接口继承过来的str和result 在这里输出
System.out.println("都变成大写: " + result);
}
}
}
4、最后主函数调用/输出 反正就是看效果 lor
Test.java
public class Test {
public static void main(String[] args)
{
String a = "asDFSdasdasd";
String b = "ddddwDFAWEHW";
//实例化实体
Customer s1 = new Customer();
//调用call方法 传入一个字符串 之后的处理和输出都交到实体类那边处理了 调用者就没事干了
s1.call(a);
s1.call(b);
}
}
结果:
流程:
1、主函数实例化实体类
2、调用call方法
3、call方法接收到主函数传进来的字符串,并且通过调用Handle类里面的change方法,把字符串传到处理逻辑里面去,对字符串进行处理。
4、Handle类处理完字符串之后,调用Skills接口的feedback方法,这个动作可以理解为,把获得的字符串和处理结果赋值到Skill下的feedback方法里面的str和result参数里面去。
5、因为Customer类的doIt方法继承于Skills,所以Skills的feedback里面的参数有什么值,doIt的feedback里面的参数就有什么值lor。
6、最后doIt把拿到的str和result输出一下,就有了结果那个截图了。
回调的开始点是在Customer的call(),而回调的结束点在Customer的doIt(),回调的关键在于Skills.java,它就像桥梁一样,完成处理函数和doIt()之间的数据过渡。