先說點(diǎn)什么
這些天绽族,沒啥事的時(shí)候,就想到什么衩藤,就去找點(diǎn)資料看吧慢,補(bǔ)充學(xué)習(xí)一下,以前老是忘記的東西慷彤,或者新聽到的東西娄蔼。這次,就記錄一下之前一直很容易弄混的概念底哗,回調(diào)。其實(shí)隨便谷歌百度一下锚沸,都能找到各種例子解析什么的跋选,不過,我相信你也會(huì)和我一樣哗蜈,看的時(shí)候覺得很簡(jiǎn)單前标,也很容易理解,不過距潘,過一陣子之后炼列,突然需要用的時(shí)候,又不清不楚了音比,又去找資料啊俭尖,看代碼啊,找例子啊洞翩。說多都是淚稽犁,我就是這樣過來的。!
第一站骚亿,來個(gè)騷問題
開始之前已亥,先想象一個(gè)場(chǎng)景:幼稚園的小朋友(邱同學(xué))剛剛學(xué)習(xí)了10以內(nèi)的加法。
老師大人在黑板上寫一個(gè)式子 “1 + 1 = ”来屠,由邱同學(xué)來填空虑椎。由于已經(jīng)學(xué)習(xí)了10以內(nèi)的加法,邱同學(xué)可以完全靠自己來計(jì)算這個(gè)題目俱笛,額捆姜,這個(gè)需求簡(jiǎn)單吧,就寫一個(gè)add(int a,int b) 不就解決了么嫂粟,是的娇未。那動(dòng)手吧:
public class Student
{
private String name = null;
public Student(String name)
{
this.name = name;
}
public void setName(String name)
{ this.name = name;
}
private int add(int a, int b)
{ return a + b;
}
public void fillBlank(int a, int b)
{
int result = add(a, b);
System.out.println(name + "心算:" + a + " + " + b + " = " + result);
}
}
邱同學(xué)在填空(fillBalnk)的時(shí)候,直接心算(add)了一下星虹,得出結(jié)果是2零抬,并將結(jié)果寫在空格里镊讼,測(cè)試:
public class Test
{
public static void main(String[] args)
{
int a = 1;
int b = 1;
Student s = new Student("邱同學(xué)");
s.fillBlank(a, b);
}
}
運(yùn)行結(jié)果如下:
邱同學(xué)心算:1 + 1 = 2
該過程完全由Student類的實(shí)例對(duì)象單獨(dú)完成,并未涉及回調(diào)機(jī)制平夜。
第二站蝶棋,進(jìn)擊的老師
課間,老師突發(fā)奇想在黑板上寫了“168 + 291 = ”讓邱同學(xué)完成忽妒,然后回辦公室了玩裙。
呀兒咯!為什么所有老師都跟邱同學(xué)過不去岸沃薄吃溅?明明超綱了好不好~~
這時(shí)候邱同學(xué)然而明顯不能再像上面那樣靠心算來完成了,正在一臉懵逼的時(shí)候鸯檬,同桌的小嫻嫻同學(xué)遞過來一個(gè)只能計(jì)算加法的計(jì)算器决侈,而邱同學(xué)恰好知道怎么用計(jì)算器,于是通過計(jì)算器計(jì)算得到結(jié)果并完成了填空喧务。
計(jì)算器的代碼為:
public class Calculator
{
public int add(int a, int b)
{ return a + b;
}
}
修改Student類赖歌,添加使用計(jì)算器的方法:
public class Student
{
private String name = null;
public Student(String name)
{
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 + "使用計(jì)算器:" + a + " + " + b + " = " + result);
}
}
測(cè)試代碼如下:
public class Test
{
public static void main(String[] args)
{
int a = 168;
int b = 291;
Student s = new Student("邱同學(xué)");
s.fillBlank(a, b);
}
}
運(yùn)行結(jié)果如下:
邱同學(xué)使用計(jì)算器:168 + 291 = 459
該過程中仍未涉及到回調(diào)機(jī)制,但是部分邱同學(xué)的部分工作已經(jīng)實(shí)現(xiàn)了轉(zhuǎn)移功茴,由計(jì)算器來協(xié)助實(shí)現(xiàn)庐冯。
第三站,暴走的老師
發(fā)現(xiàn)邱同學(xué)完成了3位數(shù)的加法坎穿,老師覺得邱同學(xué)很聰明展父,是個(gè)可塑之才。于是又在黑板上寫下了“26549 + 16487 = ”赁酝,讓邱同學(xué)上課之前完成填空犯祠,然后又回辦公室了。
邱同學(xué)看著教室外面撒歡兒的小伙伴酌呆,不禁悲從中來衡载。再不出去玩,這個(gè)課間就要廢了跋对L涤椤!F惺铡梨睁! 看著小嫻嫻再一次遞上來的計(jì)算器,邱同學(xué)心生一計(jì):讓小嫻嫻代勞娜饵。
邱同學(xué)告訴小嫻嫻題目是“26549 + 16487 = ”坡贺,然后指出填寫結(jié)果的具體位置,然后就出去快樂的玩耍了。
這里遍坟,不把小嫻嫻單獨(dú)實(shí)現(xiàn)出來拳亿,而是把這個(gè)只能算加法的計(jì)算器和小嫻嫻看成一個(gè)整體,一個(gè)會(huì)算結(jié)果還會(huì)填空的超級(jí)計(jì)算器愿伴。這個(gè)超級(jí)計(jì)算器需要傳的參數(shù)是兩個(gè)加數(shù)和要填空的位置肺魁,而這些內(nèi)容需要邱同學(xué)提前告知,也就是邱同學(xué)要把自己的一部分方法暴漏給小嫻嫻隔节,最簡(jiǎn)單的方法就是把自己的引用和兩個(gè)加數(shù)一塊告訴小嫻嫻鹅经。
因此,超級(jí)計(jì)算器的add方法應(yīng)該包含兩個(gè)操作數(shù)和邱同學(xué)自身的引用怎诫,代碼如下:
public class SuperCalculator
{
public void add(int a, int b, Student xiaoming)
{
int result = a + b;
xiaoming.fillBlank(a, b, result);
}
}
邱同學(xué)這邊現(xiàn)在已經(jīng)不需要心算瘾晃,也不需要使用計(jì)算器了,因此只需要有一個(gè)方法可以向小嫻嫻尋求幫助就行了幻妓,代碼如下:
public class Student
{
private String name = null;
public Student(String name)
{
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 + "求助小嫻嫻計(jì)算:" + a + " + " + b + " = " + result);
}
}
測(cè)試代碼如下:
public class Test
{
public static void main(String[] args)
{
int a = 26549;
int b = 16487;
Student s = new Student("邱同學(xué)");
s.callHelp(a, b);
}
}
運(yùn)行結(jié)果為:
邱同學(xué)求助小嫻嫻計(jì)算:26549 + 16487 = 43036
執(zhí)行流程為:邱同學(xué)通過自身的callHelp方法調(diào)用了小嫻嫻(new SuperCalculator())的add方法酗捌,在調(diào)用的時(shí)候?qū)⒆陨淼囊茫╰his)當(dāng)做參數(shù)一并傳入,小嫻嫻在使用計(jì)算器得出結(jié)果之后涌哲,回調(diào)了邱同學(xué)的fillBlank方法,將結(jié)果填在了黑板上的空格里尚镰。
燈燈燈阀圾!到這里,回調(diào)功能就正式登場(chǎng)了狗唉,邱同學(xué)的fillBlank方法就是我們常說的回調(diào)函數(shù)初烘。
通過這種方式,可以很明顯的看出分俯,對(duì)于完成老師的填空題這個(gè)任務(wù)上肾筐,邱同學(xué)已經(jīng)不需要等待到加法做完且結(jié)果填寫在黑板上才能去跟小伙伴們?nèi)鰵g了,填空這個(gè)工作由超級(jí)計(jì)算器小嫻嫻來做了缸剪÷痤恚回調(diào)的優(yōu)勢(shì)已經(jīng)開始體現(xiàn)了。
第四站杏节,不明真相的吃瓜婆婆
幼稚園的門口有一個(gè)頭發(fā)花白的老婆婆唬渗,每天風(fēng)雨無阻在那里擺著地?cái)傎u一些快過期的垃圾食品。由于年紀(jì)大了奋渔,腦子有些糊涂镊逝,經(jīng)常算不清楚自己掙了多少錢。有一天嫉鲸,她無意間聽到了邱同學(xué)跟小伙伴們吹噓自己如何在小嫻嫻的幫助下與幼師斗智斗勇撑蒜。于是,婆婆決定找到小嫻嫻牌超級(jí)計(jì)算器來做自己的小幫手,并提供一包衛(wèi)龍辣條作為報(bào)酬座菠。小嫻嫻經(jīng)不住誘惑狸眼,答應(yīng)了。之前辈灼,我們發(fā)現(xiàn)小嫻嫻牌超級(jí)計(jì)算器的add方法需要的參數(shù)是兩個(gè)整型變量和一個(gè)Student對(duì)象份企,但是老婆婆她不是學(xué)生,是個(gè)小商販啊巡莹,這是最尷尬的司志,所以這里肯定要做修改。這種情況下降宅,我們很自然的會(huì)想到繼承和多態(tài)骂远。如果讓邱同學(xué)這個(gè)學(xué)生和老婆婆這個(gè)小商販從一個(gè)父類進(jìn)行繼承,那么我們只需要給小嫻嫻牌超級(jí)計(jì)算器傳入一個(gè)父類的引用就可以啦腰根。
不過激才,實(shí)際使用中,考慮到j(luò)ava的單繼承额嘿,以及不希望把自身太多東西暴漏給別人瘸恼,這里使用從接口繼承的方式配合內(nèi)部類來做。
換句話說册养,小嫻嫻希望以后繼續(xù)向班里的小朋友們提供計(jì)算服務(wù)东帅,同時(shí)還能向老婆婆提供算賬服務(wù),甚至以后能夠拓展其他人的業(yè)務(wù)球拦,于是她向所有的顧客約定了一個(gè)辦法靠闭,用于統(tǒng)一的處理,也就是自己需要的操作數(shù)和做完計(jì)算之后應(yīng)該怎么做坎炼。這個(gè)統(tǒng)一的方法愧膀,小嫻嫻做成了一個(gè)接口,提供給了大家谣光,代碼如下:
public interface doJob
{
public void fillBlank(int a, int b, int result);
}
同時(shí)檩淋,小嫻嫻修改了自己的計(jì)算器,使其可以同時(shí)處理不同的實(shí)現(xiàn)了doJob接口的人抢肛,代碼如下:
public class SuperCalculator
{
public void add(int a, int b, doJob customer)
{
int result = a + b;
customer.fillBlank(a, b, result);
}
}
邱同學(xué)和老婆婆拿到這個(gè)接口之后狼钮,只要實(shí)現(xiàn)了這個(gè)接口,就相當(dāng)于按照統(tǒng)一的模式告訴小嫻嫻得到結(jié)果之后的處理辦法捡絮,按照之前說的使用內(nèi)部類來做熬芜,代碼如下:
邱同學(xué)的:
public class Student
{
private String name = null;
public Student(String name)
{
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)
{
System.out.println(name + "求助小嫻嫻計(jì)算作業(yè):" + a + " + " + b + " = " + result);
}
}
public void callHelp (int a, int b)
{ new SuperCalculator().add(a, b, new doHomeWork());
}
}
老婆婆的:
public class Popo
{
private String name = null;
public Seller(String name)
{
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)
{
System.out.println(name + "求助小嫻嫻幫忙算數(shù):" + a + " + " + b + " = " + result + "元");
}
}
public void callHelp (int a, int b)
{ new SuperCalculator().add(a, b, new doHomeWork());
}
}
測(cè)試程序如下:
public class Test
{
public static void main(String[] args)
{
int a = 60;
int b = 50;
int c = 40;
int d = 30;
Student s = new Student("邱同學(xué)");
s.callHelp(a, b);
Popo p= new Popo("不明真相的婆婆");
p.callHelp(c, d);
}
}
運(yùn)行結(jié)果為:
邱同學(xué)求助小嫻嫻計(jì)算作業(yè):a+b=110;
不明真相的婆婆求助小嫻嫻幫忙算數(shù):c+d=70;
最后廢話幾句
講道理福稳,這種騷問題表示很容易理解了吧涎拉,本來還想著說換成LOL里面中單打藍(lán)Buff的情景的,md,最近打LOL的時(shí)候遇到一個(gè)打野說了一句:憑什么中單要拿藍(lán)鼓拧,那你給我什么半火?嗨呀,好氣啊季俩,當(dāng)時(shí)的我竟然無言以對(duì)钮糖,好吧,你說服了我酌住。
所以店归,還是靠自己動(dòng)手豐衣足食,下次再寫別的酪我,一定換成中單自己打藍(lán)Buff的情景消痛。至于那位打野玩家。都哭。秩伞。。嗨呀欺矫,你好棒啊纱新。