您好,登錄后才能下訂單哦!
復(fù)用代碼是 Java 眾多引人注目的功能之一。這句話很通順,沒什么問題,但問題在于很多人并不清楚“復(fù)用”是什么。就好像我說“沉默王二是一個(gè)有趣的程序員”,唉,沉默王二是誰?
我們需要來給“復(fù)用”下一個(gè)定義。復(fù)用,說白了就是重復(fù)使用。
舉個(gè)例子,很多名人說了很多名言,我們?cè)谡f話、寫作的時(shí)候,就經(jīng)常有意無意的重復(fù)這些名言。比如說我,就特別喜歡重復(fù)使用王小波的那句名言:“從話語中,你很少能學(xué)到人性,從沉默中卻能。假如還想學(xué)得更多,那就要繼續(xù)一聲不吭 。”
上面這個(gè)例子,只能說是“復(fù)用”的一種低級(jí)的應(yīng)用,其實(shí)就是復(fù)制粘貼了。還有高級(jí)的復(fù)用方式嗎?
有,當(dāng)然有。Java 作為一種優(yōu)秀的面向?qū)ο笤O(shè)計(jì)的語言,在復(fù)用的應(yīng)用上就高級(jí)得多了。
最常見的復(fù)用方法就是繼承——使用 extends
關(guān)鍵字在基類的基礎(chǔ)上創(chuàng)建新類,新類可以直接復(fù)用基類的非 private
的屬性和方法;就像程序清單1-1那樣。
程序清單1-1:
public?class?Wangxiaosan?extends?Wangsan?{
????public?Wangxiaosan()?{
????????System.out.println("我是新類王小三");
????????setName("王老三");
????????System.out.println(getName());
????}
????public?static?void?main(String[]?args)?{
????????new?Wangxiaosan();
????}
}
class?Wangsan?{
????private?String?name;
????Wangsan()?{
????????System.out.println("我是基類王三");
????}
????public?String?getName()?{
????????return?name;
????}
????public?void?setName(String?name)?{
????????this.name?=?name;
????}
}
從程序清單 1-1 中我們可以看得出,getName() 和 setName() 方法雖然是在基類 Wangsan 中創(chuàng)建的,但可以在新類 Wangxiaosan 中使用,代碼的復(fù)用工作就這樣輕松地完成了。
另外一種常見的復(fù)用方法就是組合——在新類中創(chuàng)建已有類的對(duì)象,通過該對(duì)象來調(diào)用已有類中的非 private 的屬性和方法;就像程序清單2-1那樣。
程序清單2-1:
public?class?Tongxiangyu?{
????private?Baizhantang?boyFriend?=?new?Baizhantang();
????public?Tongxiangyu()?{
????????System.out.println("我是同??蜅5恼乒褓∠嬗?);
????????boyFriend.pointHand("郭芙蓉");
????}
????public?static?void?main(String[]?args)?{
????????new?Tongxiangyu();
????}
}
class?Baizhantang?{
????Baizhantang()?{
????????System.out.println("我是退隱江湖的盜圣白展堂");
????}
????public?void?pointHand(String?name)?{
????????System.out.println("那誰"?+?name?+?",準(zhǔn)備一下——葵花點(diǎn)穴手");
????}
}
從程序清單 2-1 中我們可以看得出,葵花點(diǎn)穴手雖然是白展堂的絕技,但作為佟掌柜的男朋友,佟掌柜要展堂點(diǎn)個(gè)穴,展堂也是不敢推辭的。你看,佟掌柜雖然是個(gè)弱女子,但自從有了展堂這個(gè)武功數(shù)一數(shù)二的男朋友,再?zèng)]有誰敢不聽話啊——厲害的組合啊。
需要注意的是,如何在繼承和組合之間做出選擇呢?
如果新類和已有類需要具有一些相似的方法和屬性時(shí),就采用繼承的形式;如果新類只是為了借用已有類的一些方法和屬性時(shí),而兩者沒有很多相似之處時(shí)就需要采用組合的形式。
還有一種復(fù)用方法是代理——在新類中創(chuàng)建代理,通過代理來操作已有類的非 private 的屬性和方法;就像程序清單 3-1 那樣。
程序清單3-1:
public?class?Member?{
????public?static?void?main(String[]?args)?{
????????Proxy?proxy?=?new?Proxy();
????????System.out.println("代理說一個(gè)藥丸十五塊");
????????proxy.buy(15);
????}
}
class?Proxy?{
????private?Shop?shop?=?new?Shop();
????public?void?buy(int?money)?{
????????System.out.println("一個(gè)藥丸十五塊");
????????shop.sale(money?-?5);
????}
}
class?Shop?{
????public?void?sale(int?money)?{
????????System.out.println("一個(gè)藥丸十塊錢");
????}
}
從程序清單 3-1 中我們可以看得出,代理的模式和組合有點(diǎn)類似,但又有差別——代理成功的隔開了新類(會(huì)員)和已有類(店鋪)的直接關(guān)系,使得已有類的方法不直接暴露在新類面前(組合的方式會(huì)將已有類的非private的方法和屬性直接暴露在新類中);與此同時(shí),代理拿到了足夠的好處。
作為代碼的生產(chǎn)者來說,我們有時(shí)候希望代碼被復(fù)用,有的時(shí)候又希望代碼不被復(fù)用。當(dāng)我們不想代碼被復(fù)用時(shí),final 關(guān)鍵字就派上用場(chǎng)了。final 這個(gè)關(guān)鍵字很形象,它本身就說明了一切——最后的,最終的;決定性的;不可更改的。
使用 final 的場(chǎng)景有三種,分別是數(shù)據(jù)、方法和類。我們來稍作說明。
1)final 數(shù)據(jù)
最常見的 final 數(shù)據(jù)就是常量了,例如:
public?class?Consts?{
????public?static?final?String?CMOWER?=?"沉默王二";
}
對(duì)于常量來說,它對(duì)于整個(gè)應(yīng)用內(nèi)的所有類都是可見的,因此是 public 的;它可以直接通過類名.常量名訪問,所以是 static 的;它是不可修改的,因此是 final 的。
另外一種常見的 final 數(shù)據(jù)就是參數(shù)了,參照程序清單 4-1。
程序清單4-1:
public?class?Cmower?{
????public?void?write(final?String?content)?{
????????//?content?+=?"猶未雪";?//?final修飾的參數(shù)是無法在方法內(nèi)部被再次修改的
????????System.out.println(content);
????}
????public?void?write1(String?content)?{
????????content?+=?"猶未雪";
????????System.out.println(content);
????}
????public?static?void?main(String[]?args)?{
????????Cmower?cmower?=?new?Cmower();
????????cmower.write("精忠報(bào)國");
????????cmower.write1("靖康恥");
????}
}
2)final 方法
在 Java 類中,所有的 private 方法都隱式地指定為 final 的(也就是說,如果你在 private 方法上加上 final 修飾符,其實(shí)是沒啥意義的)。在介紹繼承的時(shí)候,你應(yīng)該注意到我強(qiáng)調(diào)的一句話,就是新類可以直接復(fù)用基類的非 private 的屬性和方法,也就是說 private 方法是無法被繼承者修改的,因?yàn)?private 方法是 final 的。
來看程序清單 4-2,你會(huì)發(fā)現(xiàn) Wangsan 類型的 san 引用是不能調(diào)用 say(String words)
方法的,因?yàn)?private 方法是無法被繼承者修改的,盡管 Wangxiaosan 中重新定義了 say(String words)
方法。
程序清單4-2:
public?class?Wangxiaosan?extends?Wangsan?{
????public?Wangxiaosan()?{
????????say("吃中飯沒");
????}
????public?void?say(String?words)?{
????????System.out.println("王小三在說:"?+?words);
????}
????public?static?void?main(String[]?args)?{
????????Wangsan?san?=?new?Wangxiaosan();
????????//?san.say("吃晚餐沒");?//?無法訪問,并不會(huì)被覆蓋
????}
}
class?Wangsan?{
????public?Wangsan()?{
????????say("吃早飯沒");
????}
????private?void?say(String?words)?{
????????System.out.println("王三在說:"?+?words);
????}
}
3)final 類
當(dāng)我們認(rèn)為某個(gè)類就是最終的形態(tài)了,它很完美,不應(yīng)該被繼承,就可以使用final關(guān)鍵字來修飾;參照程序清單 4-3。
程序清單 4-3:
//?無法繼承
public?class?Wangxiaosan?extends?Wangsan?{
}
final?class?Wangsan?{
????public?Wangsan()?{
????????System.out.println("我就是最終形態(tài),別繼承我!");
????}
}
上一篇:Java 訪問權(quán)限控制:public、private、protected
下一篇:Java:多態(tài)乃幸福本源
微信搜索「沉默王二」公眾號(hào),關(guān)注后回復(fù)「免費(fèi)視頻」獲取 500G Java 高質(zhì)量教學(xué)視頻(已分門別類)。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。