51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 1422|回复: 0
打印 上一主题 下一主题

[原创] Java中如何实现回调函数让事实告诉你

[复制链接]
  • TA的每日心情
    无聊
    半小时前
  • 签到天数: 1052 天

    连续签到: 2 天

    [LV.10]测试总司令

    跳转到指定楼层
    1#
    发表于 2022-10-21 13:53:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    最近工作需要研究了一会别人写的库,其中充满着各种"回调函数",因此把自己理解给记录下来,存档。
      首先我们来看看回调函数 这个概念的具体由来,百度百科的示义如下:
      回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
      从上面的这段阐述之中,我们不难发现两点。
      函数回调就是将函数指针的地址当作参数传递给另一个函数。
      函数回调的用途简单来说就是进行事件的响应或者事件触发。
      既然我们知道回调函数的用途是事件的响应,那么我们就从这里入手。
      假设我们有这样一个场景,一家人坐在一起吃饭,但是我们中国的规矩是,长辈没动筷子,小辈们是不能动的,所以必须等着长辈动筷子这一事件完成之后,小辈们才能开始。
      接下来我们就用回调函数来解决。由于java中没有指针一说,故而也没了*,但是java提供了 接口帮我们实现 回调函数,俗称 接口回调。
      首先我们分别创建一个,父亲,儿子,姐姐对象。
    1. <font size="3">package zt;




    2. /**

    3. * 接口回调

    4. */

    5. public final class App {

    6.     public static void main(String[] args) {

    7.         

    8.     }

    9. }

    10. /**

    11. * 父亲类,里面有个start函数,表示开始动筷子

    12. */

    13. class Father{

    14.     private void start(){

    15.         System.out.print("父亲开始动筷子了");

    16.     }

    17. }

    18. /**

    19. * 儿子类,里面有个start函数,表示开始动筷子

    20. */

    21. class Son{

    22.     private void start(){

    23.         System.out.print("儿子可以开始动筷子了");

    24.     }

    25. }

    26. /**

    27. * 姐姐类,里面有个start函数,表示开始动筷子

    28. */

    29. class Sister{

    30.     private void start(){

    31.         System.out.print("姐姐可以开始动筷子了");

    32.     }

    33. }</font>
    复制代码
    创建好之后,我们要实现,当父亲开始动筷子之后,姐姐和弟弟才能开始动筷子。也就是我们必须将父亲动筷子这个事件传递给姐姐和弟弟对象。
      所以按照逻辑,这个父亲有一个儿子,一个女孩,并且父亲开始动筷子了,他们两个才可以动。代码如下:

    1. <font size="3">package zt;




    2. /**

    3. * 接口回调

    4. */

    5. public final class App {

    6.     public static void main(String[] args) {

    7.         new Father(new Son(),new Sister()).start();;

    8.     }

    9. }




    10. interface Start{

    11.     void Fstart(Object obj);

    12. }




    13. /**

    14. * 父亲类,里面有个start函数,表示开始动筷子

    15. */

    16. class Father{




    17.     private Sister sister;

    18.     private Son son;




    19.     Father(Son son,Sister sister){

    20.         this.son= son;

    21.         this.sister = sister;

    22.     }




    23.     public void start(){

    24.         System.out.println("父亲开始动筷子了");

    25.         son.Fstart("父亲动了筷子");

    26.         sister.Fstart("父亲动了筷子");

    27.     }

    28. }

    29. /**

    30. * 儿子类,里面有个start函数,表示开始动筷子

    31. */

    32. class Son implements Start{

    33.     private void start(){

    34.         System.out.println("儿子可以开始动筷子了");

    35.     }




    36.     @Override

    37.     public void Fstart(Object obj) {

    38.         if(obj.toString().equals("父亲动了筷子")){

    39.             start();

    40.         }

    41.     }

    42. }

    43. /**

    44. * 姐姐类,里面有个start函数,表示开始动筷子

    45. */

    46. class Sister implements Start{

    47.     private void start(){

    48.         System.out.println("姐姐可以开始动筷子了");

    49.     }




    50.     @Override

    51.     public void Fstart(Object obj) {

    52.         if(obj.toString().equals("父亲动了筷子")){

    53.             start();

    54.         }

    55.     }

    56. }</font>
    复制代码
    然后运行,结果如下:

    这样看起来是不是很灵活,万一生个二胎,再加一个就行了。当然上面的代码并不完美,面向对象的思想告诉我们,我们应该在父亲和儿子,姐姐之间再定义一个Children。代码如下,这样不管生几胎就更省事了:
    1. <font size="3">package zt;




    2. /**

    3. * 接口回调

    4. */

    5. public final class App {

    6.     public static void main(String[] args) {

    7.         new Father(new Children[] { new Son(), new Sister() }).start();

    8.     }

    9. }




    10. interface Start {

    11.     void Fstart(Object obj);

    12. }




    13. /**

    14. * 父亲类,里面有个start函数,表示开始动筷子

    15. */

    16. class Father {




    17.     private Children[] childs;




    18.     Father(Children[] childs) {

    19.         this.childs = childs;

    20.     }




    21.     public void start() {

    22.         System.out.println("父亲开始动筷子了");

    23.         for (Children ch : this.childs) {

    24.             ch.Fstart("父亲动了筷子");

    25.         }

    26.     }

    27. }




    28. class Children implements Start {




    29.     protected void start() {

    30.         System.out.println("孩子们开始动筷子");

    31.     }




    32.     @Override

    33.     public void Fstart(Object obj) {

    34.         if (obj.toString().equals("父亲动了筷子")) {

    35.             this.start();

    36.         }

    37.     }




    38. }




    39. /**

    40. * 儿子类,继承孩子类

    41. */

    42. class Son extends Children {




    43.     @Override

    44.     protected void start() {

    45.         System.out.println("儿子可以开始动筷子了");

    46.     }




    47. }




    48. /**

    49. * 姐姐类,继承孩子类

    50. */

    51. class Sister extends Children {

    52.     @Override

    53.     protected void start() {

    54.         System.out.println("姐姐可以开始动筷子了");

    55.     }

    56. }</font>
    复制代码
    这就是我最近的一些感受,说实话工作快3年了,我最近第一次感受到了面向对象编程的优美。当然也有不好的地方,面向对象把有些事复杂化了。一句话,实践是检验真理的唯一标准,纸上得来终觉浅,绝知此事要躬行。

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?(注-册)加入51Testing

    x
    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-27 10:20 , Processed in 0.064062 second(s), 25 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表