Maison  >  Article  >  Java  >  Une merveilleuse explication du mécanisme de rappel en Java (CallBack)

Une merveilleuse explication du mécanisme de rappel en Java (CallBack)

高洛峰
高洛峰original
2017-01-24 13:25:261391parcourir

Avant-propos

J'ai récemment appris Java et suis entré en contact avec le mécanisme de rappel (CallBack). Lorsque je l'ai rencontré pour la première fois, j'ai trouvé que c'était assez déroutant, et les explications pertinentes que j'ai trouvées sur Internet étaient soit expliquées en une phrase, soit relativement simples et semblaient fournir une définition du CallBack. Bien sûr, après avoir compris les rappels, je suis allé lire diverses explications sur Internet, et il n'y a vraiment eu aucun problème. Cependant, pour moi, en tant que débutant, il manque un processus étape par étape.

Le rappel est un mode d'appel bidirectionnel. Qu'est-ce que cela signifie ? C'est ce qu'on appelle un rappel. "Si vous m'appelez, je vous rappellerai."

Vous ne comprenez pas ? Peu importe, jetons un coup d'œil à cette manière sans doute plus classique d'utiliser les rappels :

la classe A implémente l'interface InA - Contexte 1

la classe A contient une classe B Référence b - Contexte 2

la classe B a une méthode test(InA a) avec un paramètre de InA - Contexte 3

L'objet de A appelle B's The la méthode passe toute seule, test(a) - cette étape équivaut à vous m'appelez

et ensuite b peut appeler la méthode d'InA dans la méthode de test - cette étape équivaut à je vous rappelle

Avant de commencer, imaginez une scène : les enfants de la maternelle viennent d'apprendre l'addition en 10 près.

Ci-dessous, je décrirai ma compréhension personnelle du mécanisme de rappel, du plus superficiel au plus profond, s'il y a quelque chose qui ne va pas, n'hésitez pas à m'éclairer !

Chapitre 1. L'origine de l'histoire

L'institutrice de maternelle a écrit une équation « 1 1 = » au tableau et Xiao Ming a rempli les blancs.

Depuis qu'il a appris l'addition en 10, Xiao Ming peut calculer ce problème entièrement par lui-même. Le code pour simuler le processus est le suivant :

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);
  }
 }

Xiao Ming remplit les blancs. (fillBalnk) À ce moment-là, j'ai fait du calcul mental (clacADD) et j'ai découvert que le résultat était 2, et j'ai écrit le résultat dans la case vide. Le code du test est le suivant :

public class Test
 {
  public static void main(String[] args)
  {
  int a = 1;
   int b = 1;
   Student s = new Student("小明");
   s.fillBlank(a, b);
  }
 }

Les résultats d'exécution sont les suivants :

Le calcul mental de Xiao Ming : 1 1 = 2

Ce processus est entièrement complété par l'objet instance de la classe Student seul et n'implique pas le mécanisme de rappel.

Chapitre 2. La recherche des ennuis par l'institutrice de maternelle

Pendant la pause, l'institutrice de maternelle a eu une idée soudaine et a écrit « 168 291 = » au tableau pour que Xiao Ming termine, puis est retourné au bureau.

Fleur à frotter ! Pourquoi tous les professeurs ont-ils des problèmes avec Xiao Ming ? C'est évidemment exagéré, d'accord ! À cette époque, il était évident que Xiao Ming ne pouvait plus s'appuyer sur le calcul mental comme ci-dessus. Lorsqu'il était confus, Xiao Hong, un camarade de classe, a remis une calculatrice qui ne pouvait calculer que l'addition (profiteur) ! ! ! ! Xiao Ming savait comment utiliser une calculatrice, il a donc utilisé la calculatrice pour calculer les résultats et remplir les blancs.

Le code de la calculatrice est :

public class Calculator
 {
  public int add(int a, int b)
  {
   return a + b;
  }
 }

Modifier la classe Etudiant et ajouter une méthode pour utiliser la calculatrice :

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);
  }
 }

Le code du test est le suivant :

public class Test
 {
  public static void main(String[] args)
  {
   int a = 168;
   int b = 291;
   Student s = new Student("小明");
   s.fillBlank(a, b);
  }
 }

Xiao Ming utilise une calculatrice : 168 291 = 459

Le mécanisme de rappel n'est toujours pas impliqué dans ce processus, mais une partie du travail de Xiao Ming a été transférée et est assistée par la calculatrice.

3. L'enseignante de la maternelle est revenue


et a découvert que Xiao Ming avait terminé l'addition de trois chiffres. L'enseignante pensait que Xiao Ming était très intelligent et doté d'un talent malléable. Il a donc écrit "26549 16487 =" au tableau et a demandé à Xiao Ming de remplir les blancs avant le cours, puis est retourné au bureau.

Xiao Ming regardait les amis s'amuser en dehors de la classe et ne pouvait s'empêcher de se sentir triste. Si nous ne sortons pas pour jouer, cette récréation sera gâchée ! ! ! ! En regardant la calculatrice que Xiao Hong lui a remise, Xiao Ming a proposé un plan : laisser Xiao Hong le faire à sa place.

Xiao Ming a dit à Xiao Hong que le sujet était "26549 16487 =", puis a indiqué l'endroit spécifique où le résultat devait être rempli, puis est sorti jouer joyeusement.

Ici, au lieu d'implémenter Xiaohong séparément, nous considérons cette calculatrice qui ne peut effectuer que des additions et Xiaohong dans son ensemble, une super calculatrice qui peut calculer les résultats et remplir les blancs. Les paramètres qui doivent être transmis à ce super calculateur sont deux ajouts et le poste à remplir, et ces contenus doivent être informés à l'avance par Xiao Ming. Cela signifie que Xiao Ming veut révéler une partie de sa méthode à Xiao Hong. Le moyen le plus simple est de dire à Xiaohong la citation et les deux ajouts ensemble.

Par conséquent, la méthode add de la super calculatrice doit contenir deux opérandes et une référence à Xiao Ming lui-même. Le code est le suivant :

Xiao Ming n'a plus besoin de calcul mental ni de calculatrice, il n'a donc besoin que d'un moyen pour demander de l'aide à Xiao Hong. Le code est le suivant :

public class SuperCalculator
 {
  public void add(int a, int b, Student xiaoming)
  {
   int result = a + b;
   xiaoming.fillBlank(a, b, result);
  }
 }

<.>

Le code du test est le suivant :

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);
  }
 }

Le résultat en cours est :

public class Test
 {
  public static void main(String[] args)
  {
   int a = 26549;
   int b = 16487;
   Student s = new Student("小明");
   s.callHelp(a, b);
  }
 }
Xiao Ming demande Xiao Hong pour obtenir de l'aide pour calculer : 26549 16487 = 43036

Le processus d'exécution est le suivant : Xiao Ming appelle la méthode add de Xiao Hong (nouveau SuperCalculator()) via sa propre méthode callHelp et utilise la sienne référence (this) comme paramètre lors de l'appel. Les nombres sont transmis ensemble. Après que Xiaohong ait utilisé la calculatrice pour obtenir le résultat, elle rappelle la méthode fillBlank de Xiaoming et remplit le résultat dans l'espace vide du tableau.

Lumière, lumière, lumière ! À ce stade, la fonction de rappel apparaît officiellement. La méthode fillBlank de Xiao Ming est ce que nous appelons souvent la fonction de rappel.

通过这种方式,可以很明显的看出,对于完成老师的填空题这个任务上,小明已经不需要等待到加法做完且结果填写在黑板上才能去跟小伙伴们撒欢了,填空这个工作由超级计算器小红来做了。回调的优势已经开始体现了。

第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有所帮助。也谢谢大家对PHP中文网的支持。

更多妙解Java中的回调机制(CallBack)相关文章请关注PHP中文网!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn