成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

為什么更推薦使用組合而非繼承關(guān)系?-創(chuàng)新互聯(lián)

前言

最近在看公司項(xiàng)目的代碼,看到了大量的繼承體系,而且還是繼承了多層,維護(hù)、閱讀都十分的困難。在查閱了一些資料以后,包括《Effective Java》一書中的第16條提到“組合優(yōu)先于繼承”。那繼承到底會(huì)暴露什么問題呢?為什么更推薦優(yōu)先使用組合呢?

創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括天全網(wǎng)站建設(shè)、天全網(wǎng)站制作、天全網(wǎng)頁制作以及天全網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,天全網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到天全省份的部分城市,未來相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

歡迎關(guān)注微信公眾號(hào)「JAVA旭陽」交流和學(xué)習(xí)

繼承帶來的問題

老實(shí)講,項(xiàng)目中為什么大量使用繼承,估計(jì)初版設(shè)計(jì)的人是想實(shí)現(xiàn)代碼的復(fù)用,但是的確帶來不少的問題。

繼承是面向?qū)ο笾匾匦灾?,語義上是表達(dá)is-a的關(guān)系,但是它會(huì)破壞封裝性。我們舉個(gè)例子:

假設(shè)我們要設(shè)計(jì)一個(gè)關(guān)于鳥的類。我們將“鳥類”這樣一個(gè)抽象的事物概念,定義為一個(gè)抽象類AbstractBird,默認(rèn)有eat吃東西的行為。所有更細(xì)分的鳥,比如麻雀、鴿子、鴕鳥等,都繼承這個(gè)抽象類。

public class AbstractBird { 
 	//... 省略其他屬性和方法... 
 	public void eat() { //... }
}

// 鴕鳥
public class Ostrich extends AbstractBird { 

}

但是,這時(shí)候搞不清楚情況的人根據(jù)需求給AbstractBird添加一個(gè)fly()的行為。但是對(duì)于鴕鳥這個(gè)子類來說,并不會(huì)飛,你如果不做任何處理,相當(dāng)于讓鴕鳥有了飛翔的功能,不符合設(shè)計(jì)。聰明的你想到了,那就重寫以下吧,拋出一個(gè)異常,如下所示:

public class AbstractBird { 
 	//... 省略其他屬性和方法... 
 	public void eat() { //... }

    public void fly() { //... }
}

// 鴕鳥
public class Ostrich extends AbstractBird { 
 //... 省略其他屬性和方法... 
 public void fly() { 
     throw new UnSupportedMethodException("I can't fly.'");  
 }  
}

這種設(shè)計(jì)思路雖然可以解決問題,但不夠優(yōu)美。因?yàn)槌锁r鳥之外,不會(huì)飛的鳥還有很多,比如企鵝。對(duì)于這些不會(huì)飛的鳥來說,我們都需要重寫fly()方法,拋出異常。而且真正好的設(shè)計(jì),對(duì)于鴕鳥和企鵝來說,就不應(yīng)該暴露給他們fly()這種不該暴露的接口,增加外部調(diào)用的負(fù)擔(dān)。

這里只提到了fly(),如果還有下蛋egg()、唱歌sing()這么多行為,總不能都冗雜在父類里吧。關(guān)鍵像我們的項(xiàng)目同事,基本上把所有的類都寫到了父類中,真的特別難以維護(hù)。

小結(jié)一下繼承帶來的問題:

  1. 子類繼承了父類所有的行為,會(huì)讓子類無意的暴露的不必要的接口,破壞封裝性。
  2. 如果繼承層級(jí)比較多,那么代碼的復(fù)雜度、可閱讀型就可想而知的難了。
  3. 另外一個(gè)點(diǎn),就是非常不好做單元測(cè)試。

針對(duì)于這種問題,組合能怎么解決呢?

組合的好處

組合,顧名思意,就是把另外一個(gè)對(duì)象做成當(dāng)前這個(gè)對(duì)象的一部分,是組成我的一部分,它也能很好的實(shí)現(xiàn)代碼的復(fù)用,語義上表達(dá)的是has-a的意思,我有xxx的能力,我有xxx的功能。

那我們看看針對(duì)上面的例子,用組合的方式該如何實(shí)現(xiàn)呢?

  • 定義接口
public interface Eatable {
    void eat();
} 
public interface Flyable { 
    void fly(); 
} 

public class EatAbility implements Eatable { 
    @Override 
    public void eat() {
        System.out.println("I can eat");
    } 
}  // 省

public class FlyAbility implements Flyable { 
    @Override 
    public void fly() {
        System.out.println("I can fly");
    } 
}  // 省
  1. 組合鴕鳥類
public class Ostrich implements Eatable {// 鴕鳥
 	private Eatable eatable = new EatAbility(); // 組合
 	//... 省略其他屬性和方法... 
	@Override 
    public void eat() { 
        eatable.eat(); // 委托
	} 
}

你看對(duì)于鴕鳥這個(gè)子類來說,只暴露了它有的能力,那就是eat,沒有暴露fly的接口。

從理論上講,通過組合、接口、委托三個(gè)技術(shù)手段,我們完全可以替換掉繼承,在項(xiàng)目中不用或者少用繼承關(guān)系,特別是一些復(fù)雜的繼承關(guān)系。

繼承真的無用武之地了?

既然面向?qū)ο笾杏欣^承這玩意,說明它并非一無是處的。

如果類之間的繼承結(jié)構(gòu)穩(wěn)定(不會(huì)輕易改變),繼承層次比較淺(比如,最多有兩層繼承關(guān)系),繼承關(guān)系不復(fù)雜,我們就可以大膽地使用繼承。反之,系統(tǒng)越不穩(wěn)定,繼承層次很深,繼承關(guān)系復(fù)雜,我們就盡量使用組合來替代繼承。

除此之外,還有一些設(shè)計(jì)模式會(huì)固定使用繼承或者組合。比如,裝飾者模式(decorator pattern)、策略模式(strategy pattern)、組合模式(composite pattern)等都使用了組合關(guān)系,而模板模式(template pattern)使用了繼承關(guān)系。

總結(jié)

不知道大家項(xiàng)目中繼承用的多嗎?其實(shí)在JDK中就有許多違反這條原則的地方,比如棧Stack類并不是Vector,不應(yīng)該有繼承關(guān)系,但是實(shí)際上就是繼承自Vector。不管如何,在項(xiàng)目中決定使用繼承而不是組合前,一定要考慮清楚,子類是否真的是父類的子類型?以后父類會(huì)不會(huì)經(jīng)常變動(dòng)的可能?父類的某些API是否存在缺陷,如果有的話也會(huì)隨著子類擴(kuò)散出去。

歡迎關(guān)注微信公眾號(hào)「JAVA旭陽」交流和學(xué)習(xí)
更多學(xué)習(xí)資料請(qǐng)移步:程序員成神之路

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購,新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧

本文標(biāo)題:為什么更推薦使用組合而非繼承關(guān)系?-創(chuàng)新互聯(lián)
分享網(wǎng)址:http://jinyejixie.com/article22/cesgjc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動(dòng)網(wǎng)站建設(shè)、網(wǎng)站排名、品牌網(wǎng)站設(shè)計(jì)、企業(yè)建站、網(wǎng)站策劃、網(wǎng)站收錄

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作
读书| 四会市| 资阳市| 秭归县| 玉林市| 绩溪县| 肥东县| 沂水县| 和龙市| 濉溪县| 日照市| 界首市| 民和| 阿巴嘎旗| 嵊州市| 星座| 治县。| 邢台市| 罗定市| 内丘县| 合肥市| 绵阳市| 山丹县| 林口县| 福州市| 启东市| 霍山县| 沂南县| 高唐县| 启东市| 潞城市| 屏东市| 夹江县| 竹北市| 黄龙县| 都昌县| 内丘县| 盐边县| 连云港市| 朝阳市| 应城市|