溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Java代碼復(fù)用的三種常用方式:繼承、組合和代理

發(fā)布時(shí)間:2020-07-24 20:03:02 來源:網(wǎng)絡(luò) 閱讀:67 作者:沉默王二 欄目:編程語言

復(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í)得多了。

01、繼承

最常見的復(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ù)用工作就這樣輕松地完成了。

02、組合

另外一種常見的復(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í)就需要采用組合的形式。

03、 代理

還有一種復(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í),代理拿到了足夠的好處。

04、final

作為代碼的生產(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é)視頻(已分門別類)。


向AI問一下細(xì)節(jié)

免責(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)容。

AI