编程史上有两个令人匪夷所思的说辞,一个是订阅,一个是回调函数。

我想应该还有很多同学为“事件的订阅”和“回调函数”所困扰,因为事情本来就不应该按这个套路来解释。

多直白,所谓的“回调函数”你完全可以线性的理解它,现在起,你只需要知道“接口”与“实现”!

常见的场景如下:

1.我写了个模块,模块中有一些功能要实现,但我暂时没空做,或者需要他人的协助来完成具体的实现。因此我先定义一个接口,接口中根据我的需要定义一些空方法,在我的模块中调用这些空方法,这些方法的具体实现交给未来实现该接口的类中去实现。

2.我写的是可复用的控件,例如点击它会完成什么功能,需要使用他的人到时候自行去填写。因此我先定义一个接口,接口中根据我的需要定义一些空方法,在我的控件中调用这些空方法,这些方法的具体实现交给未来实现该接口的类中去实现。

3.我在设计模块,就像罗列大纲一样,在接口中把该有的方法大致罗列出来,然后由实现这个接口的类来实现这些方法。

4.我写了个模块,有些功能适合放在特定的类中去实现。因此我先定义一个接口,接口中根据我的需要定义一些空方法,在我的模块中调用这些空方法,这些方法的具体实现交给未来实现该接口的类中去实现。

……

有没有发现,尽管出于不同的目的,但是他们的套路都是一样的:

1.定义接口,接口中定义空方法

2.在不方便或不适合实现方法的地方调用这些空方法

3.在实现该接口的类中具体实现这些方法

对于调用空方法的地方来说,他们调用未来会被实现的空方法,和直接调用一个现成的方法,效果是一样的。

可能光看文字描述并无助于你的理解,那么下面的代码,帮助你顺流直下秒懂这一切。

1.我写了一个可复用的控件,里面有个按钮的点击事件需要放在未来调用该控件的Activity中实现

  1. public class TitleBar extends RelativeLayout {
  2.  
  3. public TitleBar(Context context, AttributeSet attrs, int defStyleAttr) {
  4. super(context, attrs, defStyleAttr);
  5. }
  6.  
  7. public TitleBar(Context context) {
  8. super(context);
  9. }
  10.  
  11. public TitleBar(Context context, AttributeSet attrs) {
  12. super(context, attrs);
  13.  
  14. LayoutInflater.from(getContext()).inflate(R.layout.title_bar, this);
  15. }
  16.  
  17. private Button btnBack;
  18.  
  19. private void initView() {
  20. btnBack = (Button) this.findViewById(R.id.btn_back);
  21. btnBack.setOnClickListener(new OnClickListener() {
  22. @Override
  23. public void onClick(View v) {
  24.  
  25. }
  26. });
  27. }
  28. }

2.因此我定义一个接口,其中定义控件点击事件中要执行的方法的空方法,然后在控件的点击事件中调用该空方法。

  1. public class TitleBar extends RelativeLayout {
  2.  
  3. public TitleBar(Context context, AttributeSet attrs, int defStyleAttr) {
  4. super(context, attrs, defStyleAttr);
  5. }
  6.  
  7. public TitleBar(Context context) {
  8. super(context);
  9. }
  10.  
  11. public TitleBar(Context context, AttributeSet attrs) {
  12. super(context, attrs);
  13.  
  14. LayoutInflater.from(getContext()).inflate(R.layout.title_bar, this);
  15. initView();
  16. }
  17.  
  18. private Button btnBack;
  19.  
  20. private void initView() {
  21. btnBack = (Button) this.findViewById(R.id.btn_back);
  22. btnBack.setOnClickListener(new OnClickListener() {
  23. @Override
  24. public void onClick(View v) {
  25. //5.调用该接口的该空方法
  26. mTitleBarListener.btnBackClick();
  27. }
  28. });
  29. }
  30.  
  31. //1.定义该接口
  32. public interface TitleBarListener {
  33. //2.定义该空方法
  34. void btnBackClick();
  35. }
  36.  
  37. //3.在控件中定义一个该接口的成员变量
  38. private TitleBarListener mTitleBarListener;
  39.  
  40. //4.为该接口成员变量定义一个set方法,用于从实现类中传入接口的实例
  41. public void setOnTitleBarListener(TitleBarListener titleBarListener) {
  42. this.mTitleBarListener = titleBarListener;
  43. }
  44. }

3.在Activity中使用该控件,传入该接口的实例,并实现该方法

  1. public class ActivityOne extends AppCompatActivity {
  2.  
  3. @Override
  4. protected void onCreate(@Nullable Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.aty_one);
  7. initView();
  8. }
  9.  
  10. private TitleBar titleBar;
  11.  
  12. private void initView() {
  13. titleBar = (TitleBar) findViewById(R.id.titleBar);
  14. //6.调用该接口的set方法,将接口的实例传入并具体实现控件中调用的空方法
  15. titleBar.setOnTitleBarListener(new TitleBar.TitleBarListener() {
  16. @Override
  17. public void btnBackClick() {
  18. //此处填充我们具体要实现的内容
  19. }
  20. });
  21. }
  22. }

怎么样,容易理解吧。未来我们一定还会遇到各种各样奇葩的说辞,需要你多实践,透过表象看其本质,这样就不能轻易的被迷惑了。

Java|今天起,别再扯订阅和回调函数的更多相关文章

  1. MQTT介绍(3)java模拟MQTT的发布,订阅

    MQTT目录: MQTT简单介绍 window安装MQTT服务器和client java模拟MQTT的发布,订阅 在此强调一下mqtt的使用场景: 1.不可靠.网络带宽小的网络 2.运行的设备CPU. ...

  2. Java是否还能再辉煌十年?

    目录 Java是否还能再辉煌十年? 一.前言 二.如今的Java语言 2.1 位居TIOBE榜首 2.2 革命性的语言 三.Java受到的挑战 3.1 后台服务器软件的语言竞争 3.1.1 Pytho ...

  3. JDBC 4.0 开始Java操作数据库不用再使用 Class.forName加载驱动类了

    JDBC 4.0 开始Java操作数据库不用再使用 Class.forName加载驱动类了 代码示例 转自 https://docs.oracle.com/javase/tutorial/jdbc/o ...

  4. Java回调函数

    维基百科上的定义:在计算机程序设计中,回调函数,或简称回调,是指通过函数参数传递到其它代码的,某一块可执行代码的引用.这一设计允许了底层代码调用在高层定义的子程序. 所谓回调,就是客户程序C调用服务程 ...

  5. Java 回调函数

    下面使用java回调函数来实现一个测试函数运行时间的工具类: 如果我们要测试一个类的方法的执行时间,通常我们会这样做: public class TestObject { /** * 一个用来被测试的 ...

  6. java回调函数,看完就懂

    java回调函数在网上了看了些例子,比较绕,不够清晰,自己写的一个例子比较通俗,java回调其实很简单. 举个例子我是类B,我有个方法叫b(),现在我要调用类A中的方法a(),写个代码就是: publ ...

  7. Java回调函数的理解与实现

    回调函数,或简称回调,是指通过函数参数传递到其它代码的,某一块可执行代码的引用.这一设计允许了底层代码调用在高层定义的子程序. 在Java里面,我们使用接口来实现回调.举个例子 所谓的回调,就是程序员 ...

  8. Java中的回调函数学习-深入浅出

    Java中的回调函数一般来说分为下面几步: 声明回调函数的统一接口interface A.包括方法callback(); 在调用类caller内将该接口设置为私有成员private A XXX; 在c ...

  9. java回调函数详解

    声明:博客参考于https://www.cnblogs.com/yangmin86/p/7090882.html,谢谢哥们 回调函数:是指在A类执行代码时,调用了B类中的方法,但B类中的方法执行了A类 ...

随机推荐

  1. python2.7 报错(UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 0: ordinal not in range(128))

    报错: 原来用的python3.5版本后来改为2.7出现了这个错误里面的中文无法显示 UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 ...

  2. linux回退到上次访问目录

    cd / cd ..  回到上级目录 cd - 回到上次访问目录

  3. jemalloc在linux上从安装到使用

    jemalloc在linux上从安装到使用 上次在引导大家安装Redis时提到可能会报错:  发现了redis有用到jemalloc. 首先,jemalloc是干什么的? 我们看看作者自己的介绍: j ...

  4. Sublime 3 如何设置xftp 排除文件夹“bower_components”,“node_modules”

    “bower_components”,“node_modules”这个文件夹,作为模块得引用文件,不需要下载本地进行编码,这里得文件非常多,若是不把这个两个文件夹排除掉掉话,通过xftp下载所有文件的 ...

  5. Swing中弹出对话框的几种方式_JOptionPane.showMessageDialog等详解

    Swing中弹出对话框的几种方式_JOptionPane.showMessageDialog等详解   在swing中,基于业务的考量,会有对话框来限制用户的行为及对用户的动作进行提示. Swing中 ...

  6. MD5加密

    public string Second_MD5(string str) { MD5 md5 = MD5.Create();//创建MD5实例 byte[] strbyte = Encoding.UT ...

  7. checkbox check all or ancheck all

    <script type="text/javascript" src="js/jQuery.1.8.3.min.js"></script> ...

  8. 一键启动NameNode和DataNode--shell脚本

    使用shell脚本,一键启动hadoop中的NameNode和DataNode.分为普通版和装逼版.装逼版较普通版多了很多判断和信息提示,当然主要还是为了我联系shell脚本而写的. 如果想实现复用, ...

  9. 用 javassist 来修改 class 文件

    import javassist.ClassPool; import javassist.CtClass; import javassist.CtMethod; public class Test { ...

  10. addEventListener详解

    为什么需要addEventListener? 先来看一个片段: html代码 <div id="box">追梦子</div> 用on的代码 window.o ...