ホームページ  >  記事  >  Java  >  JAVAのコールバック機構CallBackの詳細説明

JAVAのコールバック機構CallBackの詳細説明

高洛峰
高洛峰オリジナル
2017-01-24 13:34:281070ブラウズ

はじめに

CallBack はコールバックを意味します。Windows プログラミングに慣れている人は「コールバック関数」という 4 つの単語をよく知っていますが、Java プログラマはそれについてあまり知らないかもしれません。 「コールバック関数」または「コールバックメソッド」は、ソフトウェアの設計と開発において非常に重要な概念です。「コールバック関数」の概念を習得することは、(どの言語を使用するかに関係なく)プログラマにとって非常に必要です。

私は最近 Java を学び、コールバック機構 (CallBack) に触れました。初めてこれに出会ったとき、非常にわかりにくいと感じましたが、インターネットで見つけた関連する説明は、一文で説明されているか、比較的単純で CallBack の定義を提供しているように見えました。もちろん、コールバックを理解した後、インターネットでさまざまな説明を読みましたが、特に問題はありませんでした。ただし、初心者の私にとっては、段階的なプロセスが欠けています。ここでは、コールバックメカニズムについての私の個人的な理解を浅いところから深いところまで順番に説明します。間違っていることがあれば、遠慮なくご指摘ください。

始める前に、次のような場面を想像してください。幼稚園児が 10 以内の足し算を学んだばかりです。

第 1 章 物語の起源

幼稚園の先生が黒板に「1 + 1 = 」という方程式を書き、シャオミンが空欄を埋めました。

Xiao Ming は 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);
}
}

Xiao Ming が空白を埋めるとき (fillBalnk)、直接計算します。 mental (clacADD) しばらくすると、結果は 2 になり、結果を空白のボックスに書き込みます。テストコードは次のとおりです:

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

実行結果は次のとおりです:

Xiao Ming の暗算: 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 = ;
int b = ;
Student s = new Student("小明");
s.fillBlank(a, b);
}
}

実行結果

Xiao Ming は電卓を使用します: 168 + 291 = 459

コールバック メカニズムはまだこのプロセスに関与していませんが、Xiao Ming の作業の一部は転送され、電卓によって支援されています。

3. 幼稚園の先生が戻ってきて

、シャオ・ミンが3桁の数字の足し算を終えていることに気づきました。先生はシャオ・ミンがとても賢くて、順応性のある才能があると思いました。そこで彼は黒板に「26549 + 16487 = 」と書き、授業に行く前にシャオミンに空欄を埋めるように頼み、それからオフィスに戻りました。

シャオミンは教室の外で友達が楽しんでいるのを見て、悲しくならずにいられませんでした。遊びに行かないと、この休み場が台無しになってしまうよ! ! ! ! シャオホンが再び手渡した電卓を眺めながら、シャオミンはある計画を思いついた。それはシャオホンにやらせてみることだった。

シャオミンはシャオホンに、お題は「26549 + 16487 = 」であると伝え、結果を記入する具体的な場所を指定して、楽しく遊びに出かけました。

ここでは、Xiaohongを個別に実装するのではなく、足し算とXiaohong全体を追加することしかできないこの電卓を、結果を計算して空白を埋めることができるスーパー電卓として考えます。このスーパー電卓に渡す必要があるパラメータは 2 つの加数と埋められる位置であり、これらの内容は事前にシャオ ミンに通知する必要があります。つまり、シャオ ミンは自分のメソッドの一部をシャオ ホンに公開したいと考えています。最も簡単な方法は、Xiaohong に引用と 2 つの足し算を一緒に伝えることです。

したがって、スーパー電卓の add メソッドには 2 つのオペランドと Xiao Ming 自身への参照が含まれている必要があります。コードは次のとおりです:

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

Xiao Ming は暗算や電卓を使用する必要がなくなりました。彼はXiaohongに助けを求める方法が必要なだけです。 コードは次のとおりです:

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 = ;
int b = ;
Student s = new Student("小明");
s.callHelp(a, b);
}
}

実行結果は次のとおりです:

Xiao Mingは尋ねます。シャオ・ホンの計算のヘルプ: 26549 + 16487 = 43036
実行プロセスは次のとおりです: シャオ・ミンは、自分の callHelp メソッドを介してシャオ・ホンの add メソッド (new SuperCalculator()) を呼び出します。呼び出し時に、彼自身の参照

(これ。 Xiao Hon 電卓を使用して結果を取得した後、Xiao Ming の fillBlank メソッドが呼び戻され、結果が黒板の空白スペースに埋められます。

軽い、軽い、軽い!この時点で、Xiao Ming の fillBlank メソッドが正式に登場します。これは、私たちがよくコールバック関数と呼ぶものです。

この方法を通じて、教師の穴埋め問題を完了するタスクについて、シャオミンは足し算が完了して結果が黒板に記入されるまで待つ必要がなくなったことがはっきりとわかります。友達と楽しむ前に、空白を埋めてください。この作業はスーパーコンピューター Xiaohong によって行われました。撤退の利点はすでに現れ始めています。

第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 = ;
int b = ;
int c = ;
int d = ;
Student s = new Student("小明");
Seller s = new Seller("老婆婆");
s.callHelp(a, b);
s.callHelp(c, d);
}
}

运行结果如下:

小明求助小红计算:56 + 31 = 87

老婆婆求助小红算账:26497 + 11256 = 37753元 

最后的话

可以很明显的看到,小红已经把这件事情当做一个事业来做了,看她给接口命的名字doJob就知道了。

更多详解 JAVA的回调机制CallBack相关文章请关注PHP中文网!

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。