51Testing软件测试论坛

标题: Java中如何实现回调函数让事实告诉你 [打印本页]

作者: lsekfe    时间: 2022-10-21 13:53
标题: Java中如何实现回调函数让事实告诉你
最近工作需要研究了一会别人写的库,其中充满着各种"回调函数",因此把自己理解给记录下来,存档。
  首先我们来看看回调函数 这个概念的具体由来,百度百科的示义如下:
  回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
  从上面的这段阐述之中,我们不难发现两点。
  函数回调就是将函数指针的地址当作参数传递给另一个函数。
  函数回调的用途简单来说就是进行事件的响应或者事件触发。
  既然我们知道回调函数的用途是事件的响应,那么我们就从这里入手。
  假设我们有这样一个场景,一家人坐在一起吃饭,但是我们中国的规矩是,长辈没动筷子,小辈们是不能动的,所以必须等着长辈动筷子这一事件完成之后,小辈们才能开始。
  接下来我们就用回调函数来解决。由于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>
复制代码
然后运行,结果如下:
[attach]144155[/attach]
这样看起来是不是很灵活,万一生个二胎,再加一个就行了。当然上面的代码并不完美,面向对象的思想告诉我们,我们应该在父亲和儿子,姐姐之间再定义一个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软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2