JAVA回调机制(CallBack)详解
序言
最近学习java,接触到了回调机制(CallBack)。初识时感觉比较混乱,而且在网上搜索到的相关的讲解,要么一言带过,要么说的比较单纯的像是给CallBack做了一个定义。当然了,我在理解了回调之后,再去看网上的各种讲解,确实没什么问题。但是,对于初学的我来说,缺了一个循序渐进的过程。此处,将我对回调机制的个人理解,按照由浅到深的顺序描述一下,如有不妥之处,望不吝赐教!
开始之前,先想象一个场景:幼稚园的小朋友刚刚学习了10以内的加法。
第1章. 故事的缘起
幼师在黑板上写一个式子 “1 + 1 = ”,由小明同学来填空。
由于已经学习了10以内的加法,小明同学可以完全靠自己来计算这个题目,模拟该过程的代码如下:
public class Student
{
private String name = null; public Student(String name)
{
// TODO Auto-generated constructor stub
this.name = name;
} public void setName(String name)
{
this.name = name;
} private int calcADD(int a, int b)
{
return a + b;
} public void fillBlank(int a, int b)
{
int result = calcADD(a, b);
System.out.println(name + "心算:" + a + " + " + b + " = " + result);
}
}
小明同学在填空(fillBalnk)的时候,直接心算(clacADD)了一下,得出结果是2,并将结果写在空格里。测试代码如下:
public class Test
{
public static void main(String[] args)
{
int a = 1;
int b = 1;
Student s = new Student("小明");
s.fillBlank(a, b);
}
}
运行结果如下:
小明心算:1 + 1 = 2
该过程完全由Student类的实例对象单独完成,并未涉及回调机制。
第2章. 幼师的找茬
课间,幼师突发奇想在黑板上写了“168 + 291 = ”让小明完成,然后回办公室了。
花擦!为什么所有老师都跟小明过不去啊?明明超纲了好不好!这时候小明同学明显不能再像上面那样靠心算来完成了,正在懵逼的时候,班上的小红同学递过来一个只能计算加法的计算器(奸商啊)!!!!而小明同学恰好知道怎么用计算器,于是通过计算器计算得到结果并完成了填空。
计算器的代码为:
public class Calculator
{
public int add(int a, int b)
{
return a + b;
}
}
修改Student类,添加使用计算器的方法:
public class Student
{
private String name = null; public Student(String name)
{
// TODO Auto-generated constructor stub
this.name = name;
} public void setName(String name)
{
this.name = name;
} @SuppressWarnings("unused")
private int calcADD(int a, int b)
{
return a + b;
} private int useCalculator(int a, int b)
{
return new Calculator().add(a, b);
} public void fillBlank(int a, int b)
{
int result = useCalculator(a, b);
System.out.println(name + "使用计算器:" + a + " + " + b + " = " + result);
}
}
测试代码如下:
public class Test
{
public static void main(String[] args)
{
int a = 168;
int b = 291;
Student s = new Student("小明");
s.fillBlank(a, b);
}
}
运行结果如下:
小明使用计算器:168 + 291 = 459
该过程中仍未涉及到回调机制,但是部分小明的部分工作已经实现了转移,由计算器来协助实现。
3. 幼师回来了
发现小明完成了3位数的加法,老师觉得小明很聪明,是个可塑之才。于是又在黑板上写下了“26549 + 16487 = ”,让小明上课之前完成填空,然后又回办公室了。
小明看着教室外面撒欢儿的小伙伴,不禁悲从中来。再不出去玩,这个课间就要废了啊!!!! 看着小红再一次递上来的计算器,小明心生一计:让小红代劳。
小明告诉小红题目是“26549 + 16487 = ”,然后指出填写结果的具体位置,然后就出去快乐的玩耍了。
这里,不把小红单独实现出来,而是把这个只能算加法的计算器和小红看成一个整体,一个会算结果还会填空的超级计算器。这个超级计算器需要传的参数是两个加数和要填空的位置,而这些内容需要小明提前告知,也就是小明要把自己的一部分方法暴漏给小红,最简单的方法就是把自己的引用和两个加数一块告诉小红。
因此,超级计算器的add方法应该包含两个操作数和小明自身的引用,代码如下:
public class SuperCalculator
{
public void add(int a, int b, Student xiaoming)
{
int result = a + b;
xiaoming.fillBlank(a, b, result);
}
}
小明这边现在已经不需要心算,也不需要使用计算器了,因此只需要有一个方法可以向小红寻求帮助就行了,代码如下:
public class Student
{
private String name = null; public Student(String name)
{
// TODO Auto-generated constructor stub
this.name = name;
} public void setName(String name)
{
this.name = name;
} public void callHelp (int a, int b)
{
new SuperCalculator().add(a, b, this);
} public void fillBlank(int a, int b, int result)
{
System.out.println(name + "求助小红计算:" + a + " + " + b + " = " + result);
}
}
测试代码如下:
public class Test
{
public static void main(String[] args)
{
int a = 26549;
int b = 16487;
Student s = new Student("小明");
s.callHelp(a, b);
}
}
运行结果为:
小明求助小红计算:26549 + 16487 = 43036
执行流程为:小明通过自身的callHelp方法调用了小红(new SuperCalculator())的add方法,在调用的时候将自身的引用(this)当做参数一并传入,小红在使用计算器得出结果之后,回调了小明的fillBlank方法,将结果填在了黑板上的空格里。
灯灯灯!到这里,回调功能就正式登场了,小明的fillBlank方法就是我们常说的回调函数。
通过这种方式,可以很明显的看出,对于完成老师的填空题这个任务上,小明已经不需要等待到加法做完且结果填写在黑板上才能去跟小伙伴们撒欢了,填空这个工作由超级计算器小红来做了。回调的优势已经开始体现了。
第4章. 门口的婆婆
幼稚园的门口有一个头发花白的老婆婆,每天风雨无阻在那里摆着地摊卖一些快过期的垃圾食品。由于年纪大了,脑子有些糊涂,经常算不清楚自己挣了多少钱。有一天,她无意间听到了小明跟小伙伴们吹嘘自己如何在小红的帮助下与幼师斗智斗勇。于是,婆婆决定找到小红牌超级计算器来做自己的小帮手,并提供一包卫龙辣条作为报酬。小红经不住诱惑,答应了。
回看一下上一章的代码,我们发现小红牌超级计算器的add方法需要的参数是两个整型变量和一个Student对象,但是老婆婆她不是学生,是个小商贩啊,这里肯定要做修改。这种情况下,我们很自然的会想到继承和多态。如果让小明这个学生和老婆婆这个小商贩从一个父类进行继承,那么我们只需要给小红牌超级计算器传入一个父类的引用就可以啦。
不过,实际使用中,考虑到java的单继承,以及不希望把自身太多东西暴漏给别人,这里使用从接口继承的方式配合内部类来做。
换句话说,小红希望以后继续向班里的小朋友们提供计算服务,同时还能向老婆婆提供算账服务,甚至以后能够拓展其他人的业务,于是她向所有的顾客约定了一个办法,用于统一的处理,也就是自己需要的操作数和做完计算之后应该怎么做。这个统一的方法,小红做成了一个接口,提供给了大家,代码如下:
public interface doJob
{
public void fillBlank(int a, int b, int result);
}
因为灵感来自帮小明填空,因此小红保留了初心,把所有业务都当做填空(fillBlank)来做。
同时,小红修改了自己的计算器,使其可以同时处理不同的实现了doJob接口的人,代码如下:
public class SuperCalculator
{
public void add(int a, int b, doJob customer)
{
int result = a + b;
customer.fillBlank(a, b, result);
}
}
小明和老婆婆拿到这个接口之后,只要实现了这个接口,就相当于按照统一的模式告诉小红得到结果之后的处理办法,按照之前说的使用内部类来做,代码如下:
小明的:
public class Student
{
private String name = null; public Student(String name)
{
// TODO Auto-generated constructor stub
this.name = name;
} public void setName(String name)
{
this.name = name;
} public class doHomeWork implements doJob
{ @Override
public void fillBlank(int a, int b, int result)
{
// TODO Auto-generated method stub
System.out.println(name + "求助小红计算:" + a + " + " + b + " = " + result);
} } public void callHelp (int a, int b)
{
new SuperCalculator().add(a, b, new doHomeWork());
}
}
老婆婆的:
public class Seller
{
private String name = null; public Seller(String name)
{
// TODO Auto-generated constructor stub
this.name = name;
} public void setName(String name)
{
this.name = name;
} public class doHomeWork implements doJob
{ @Override
public void fillBlank(int a, int b, int result)
{
// TODO Auto-generated method stub
System.out.println(name + "求助小红算账:" + a + " + " + b + " = " + result + "元");
} } public void callHelp (int a, int b)
{
new SuperCalculator().add(a, b, new doHomeWork());
}
}
测试程序如下:
public class Test
{
public static void main(String[] args)
{
int a = 56;
int b = 31;
int c = 26497;
int d = 11256;
Student s1 = new Student("小明");
Seller s2 = new Seller("老婆婆"); s1.callHelp(a, b);
s2.callHelp(c, d);
}
}
运行结果如下:
小明求助小红计算:56 + 31 = 87
老婆婆求助小红算账:26497 + 11256 = 37753元
最后的话
可以很明显的看到,小红已经把这件事情当做一个事业来做了,看她给接口命的名字doJob就知道了。
有人也许会问,为什么老婆婆摆摊能挣那么多钱? 你的关注点有问题好吗!!这里聊的是回调机制啊!!
我只知道,后来小红的业务不断扩大,终于在幼稚园毕业之前,用挣到的钱买了人生的第一套房子。
完!!!
JAVA回调机制(CallBack)详解的更多相关文章
- [转]JAVA回调机制(CallBack)详解
看见一篇博客比较通俗的解释了回调机制,转载一下,感谢原文作者Bro__超,原文地址:http://www.cnblogs.com/heshuchao/p/5376298.html 序言 最近学习jav ...
- java反射机制深入详解
java反射机制深入详解 转自:http://www.cnblogs.com/hxsyl/archive/2013/03/23/2977593.html 一.概念 反射就是把Java的各种成分映射成 ...
- Java SPI机制实战详解及源码分析
背景介绍 提起SPI机制,可能很多人不太熟悉,它是由JDK直接提供的,全称为:Service Provider Interface.而在平时的使用过程中也很少遇到,但如果你阅读一些框架的源码时,会发现 ...
- Java回调机制总结
调用和回调机制 在一个应用系统中, 无论使用何种语言开发, 必然存在模块之间的调用, 调用的方式分为几种: 1.同步调用 同步调用是最基本并且最简单的一种调用方式, 类A的方法a()调用类B的方法b( ...
- JAVA 回调机制(callback)
序言 最近学习java,接触到了回调机制(CallBack).初识时感觉比较混乱,而且在网上搜索到的相关的讲解,要么一言带过,要么说的比较单纯的像是给CallBack做了一个定义.当然了,我在理解了回 ...
- “全栈2019”Java第一百一十三章:什么是回调?回调应用场景详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- java web.xml配置详解(转)
源出处:java web.xml配置详解 1.常规配置:每一个站的WEB-INF下都有一个web.xml的设定文件,它提供了我们站台的配置设定. web.xml定义: .站台的名称和说明 .针对环境参 ...
- java回调机制及其实现(转)
1. 什么是回调函数 回调函数,顾名思义,用于回调的函数.回调函数只是一个功能片段,由用户按照回调函数调用约定来实现的一个函数.回调函数是一个工作流的一部分,由工作流来决定函数的调用(回调)时机.回调 ...
- Java的JDBC事务详解
Java的JDBC事务详解 分类: Hibernate 2010-06-02 10:04 12298人阅读 评论(9) ...
随机推荐
- 前端极易被误导的css选择器权重计算及css内联样式的妙用技巧
记得大学时候,专业课的网页设计书籍里面讲过css选择器权重的计算:id是100,class是10,html标签是5等等,然后全部加起来的和进行比较... 我只想说:真是误人子弟,害人不浅! 最近,在前 ...
- XStream将java对象转换为xml时,对象字段中的下划线“_”,转换后变成了两个的解决办法
在前几天的一个项目中,由于数据库字段的命名原因 其中有两项:一项叫做"市场价格"一项叫做"商店价格" 为了便于区分,遂分别将其命名为market ...
- C语言 · 矩形面积交
问题描述 平面上有两个矩形,它们的边平行于直角坐标系的X轴或Y轴.对于每个矩形,我们给出它的一对相对顶点的坐标,请你编程算出两个矩形的交的面积. 输入格式 输入仅包含两行,每行描述一个矩形. 在每行中 ...
- 【Win 10 应用开发】在App所在的进程中执行后台任务
在以往版本中,后台任务都是以独立的专用进程来运行,因此,定义后台任务代码的类型都要位于 Windows 运行时组件项目中. 不过,在14393中,SDK 作了相应的扩展,不仅支持以前的独立进程中运行后 ...
- 【Big Data】HADOOP集群的配置(一)
Hadoop集群的配置(一) 摘要: hadoop集群配置系列文档,是笔者在实验室真机环境实验后整理而得.以便随后工作所需,做以知识整理,另则与博客园朋友分享实验成果,因为笔者在学习初期,也遇到不少问 ...
- isEmpty和isNull()区别
isEmpty和isNull()区别一个NULL字符串一定是一个空串,一个空串未必是一个NULL字符串例如:QString().isNull(): //结果为trueQString().isEm ...
- Android中Activity运行时屏幕方向与显示方式详解
现在我们的手机一般都内置有方向感应器,手机屏幕会根据所处位置自动进行横竖屏切换(前提是未锁定屏幕方向).但有时我们的应用程序仅限在横屏或者竖屏状态下才可以运行,此时我们需要锁定该程序Activity运 ...
- Prometheus 系统监控方案 一
最近一直在折腾时序类型的数据库,经过一段时间项目应用,觉得十分不错.而Prometheus又是刚刚推出不久的开源方案,中文资料较少,所以打算写一系列应用的实践过程分享一下. Prometheus 是什 ...
- 在Redhat上为.Net 项目构建基于Jenkins + Github + Mono 的持续集成环境
在Redhat enterprise 6.5 的服务器上,为在gutub 上的 .net 项目构建一个持续集成环境,用到了Jenkins和mono.因公司的服务器在内网,访问外网时要通过代理,所以在很 ...
- Nodejs之MEAN栈开发(五)---- Angular入门与页面改造
这个系列一共会涉及两个JavaScript框架的讲解,一个是Express用做后端,一个是Angular用于前端.和Express一样,Angular分离内容,处理视图.数据和逻辑.和MVC模式很相似 ...