成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java中消除實(shí)現(xiàn)繼承和面向接口編程

開(kāi)發(fā) 后端
相比于接口繼承,實(shí)現(xiàn)繼承的問(wèn)題要更多,它會(huì)帶來(lái)更多的耦合問(wèn)題,但接口繼承也是有問(wèn)題的。本文向您介紹在Java中消除實(shí)現(xiàn)繼承和面向接口編程。
在匆忙之際理清消除實(shí)現(xiàn)繼承和面向接口編程這樣兩個(gè)大問(wèn)題可不是一件容易的事情,尤其考慮到自身的認(rèn)識(shí)水平。坦白的說(shuō),這又是一篇“炒冷飯”的文章,但這“冷飯”又確實(shí)不好炒。因此,在閱讀了這篇文章之后,你可要批判地接受(拒絕)我的觀點(diǎn),盡管我的觀點(diǎn)也是來(lái)自于別人的觀點(diǎn)。

繼承是面向?qū)ο笾泻苤匾母拍睢H绻紤]到Java語(yǔ)言特性,繼承分為兩種:接口繼承和實(shí)現(xiàn)繼承。這只是技術(shù)層面的問(wèn)題,即便C++中不存在接口的概念,但它的虛基類(lèi)實(shí)際上也相當(dāng)于接口。對(duì)于OO的初學(xué)者來(lái)說(shuō),他們很希望自己的程序中出現(xiàn)大量的繼承,因?yàn)檫@樣看起來(lái)很OO。但濫用繼承會(huì)帶來(lái)很多問(wèn)題,盡管有時(shí)候我們又不得不使用繼承解決問(wèn)題。

相比于接口繼承,實(shí)現(xiàn)繼承的問(wèn)題要更多,它會(huì)帶來(lái)更多的耦合問(wèn)題。但接口繼承也是有問(wèn)題的,這是繼承本身的問(wèn)題。實(shí)現(xiàn)繼承的很多問(wèn)題出于其自身實(shí)現(xiàn)上,這也是消除實(shí)現(xiàn)繼承的難點(diǎn),因此這里重點(diǎn)討論實(shí)現(xiàn)繼承的問(wèn)題。

舉個(gè)例子(這個(gè)例子實(shí)在太老套了)。我要實(shí)現(xiàn)一個(gè)Stack類(lèi),我想當(dāng)然地選擇Stack類(lèi)繼承于ArrayList類(lèi)(你也可以認(rèn)為我很想OO些或者出于本性的懶惰);現(xiàn)在又有了新的需求,需要實(shí)現(xiàn)一個(gè)線程安全的Stack,我又定義了一個(gè)ConcurrentStack類(lèi)繼承于Stack并覆蓋了Stack中的部分代碼。

因?yàn)镾tack繼承于ArrayList,Stack不得不對(duì)外暴露出ArrayList所有的public方法,即便其中的某些方法對(duì)它可能是不需要的;甚至更糟的是,可能其中的某些方法能改變Stack的狀態(tài),而Stack對(duì)這些改變并不知情,這就會(huì)造成Stack的邏輯錯(cuò)誤。

如果我要在ArrayList中添加新的方法,這個(gè)方法就有可能在邏輯上破壞它的派生類(lèi)Stack、 ConcurrentStack。因此在基類(lèi)(父類(lèi))添加方法(修改代碼)時(shí),必須檢查這些修改是否會(huì)對(duì)派生類(lèi)產(chǎn)生影響;如果產(chǎn)生影響的話,就不得不對(duì)派生類(lèi)做進(jìn)一步的修改。如果類(lèi)的繼承體系不是一個(gè)人完成的,或者是修改別人的代碼的情況下,很可能因?yàn)槔^承產(chǎn)生難以覺(jué)察的BUG。

問(wèn)題還是有的。我們有時(shí)會(huì)見(jiàn)到這樣的基類(lèi),它的一些方法只是拋出異常,這意味著如果派生類(lèi)支持這個(gè)方法就重寫(xiě)它,否則就如父類(lèi)一樣拋出異常表明其不支持這個(gè)方法的調(diào)用。我們也能見(jiàn)到它的一個(gè)變種,父類(lèi)的方法是抽象的,但不是所有的子類(lèi)都支持這個(gè)方法,不支持的方法就以拋出異常的方式表明立場(chǎng)。這種做法是很不友好和很不安全的,它們只能在運(yùn)行時(shí)被“僥幸捕捉”,而很多漏網(wǎng)的異常方法可能會(huì)在某一天突然出現(xiàn),讓人不知所措。

引起上面問(wèn)題的很重要的原因便是基類(lèi)和派生類(lèi)之間的耦合。往往只是對(duì)基類(lèi)做了小小的改動(dòng),卻不得不重構(gòu)它們的所有的派生類(lèi),這就是臭名昭著的“脆弱的基類(lèi)”問(wèn)題。由于類(lèi)之間的關(guān)系是存在的,因此耦合是不可避免的甚至是必要的。但在做OO設(shè)計(jì)時(shí),當(dāng)遇到如基類(lèi)和派生類(lèi)之間的強(qiáng)耦合關(guān)系,我們就要思量思量,是否一定需要繼承呢?是否會(huì)有其他的更優(yōu)雅的替代方案呢?如果一定要學(xué)究的話,你會(huì)在很多書(shū)中會(huì)看到這樣的原則:如果兩個(gè)類(lèi)之間是IS-A關(guān)系,那么就使用繼承;如果兩個(gè)類(lèi)之間是Has-A的關(guān)系,那么就使用委派。很多時(shí)候這條原則是適用的,但I(xiàn)S-A并不能做為使用繼承的絕對(duì)理由。有時(shí)為了消除耦合帶來(lái)的問(wèn)題,使用委派等方法會(huì)更好地封裝實(shí)現(xiàn)細(xì)節(jié)。繼承有時(shí)會(huì)對(duì)外及向下暴露太多的信息,在GOF的設(shè)計(jì)模式中,有很多模式的目的就是為了消除繼承。

關(guān)于何時(shí)采用繼承,一個(gè)重要的原則是確定方法是否能夠共享。比如DAO ,可以將通用的CRUD 方法定在一個(gè)抽象DAO 中,具體的DAO 都派生自這個(gè)抽象類(lèi)。嚴(yán)格的說(shuō),抽象DAO 和派生的DAO 實(shí)現(xiàn)并不具有IS -A 關(guān)系,我們只是為了避免重復(fù)的方法定義和實(shí)現(xiàn)而作出了這一技術(shù)上的選擇。可以說(shuō),使用接口還是抽象類(lèi)的原則是,如果多個(gè)派生類(lèi)的方法內(nèi)容沒(méi)有共同的地方,就用接口作為抽象;如果 多個(gè)派生類(lèi) 的方法含有共同的地方,就用抽象類(lèi)作為抽象。當(dāng)這一原則不適用于接口繼承,如果出現(xiàn)接口繼承,就會(huì)相應(yīng)地有實(shí)現(xiàn)繼承(基類(lèi)更多的是抽象類(lèi))。

現(xiàn)在說(shuō)說(shuō)面向接口編程。在眾多的敏捷方法中,面向接口編程總是被大師們反復(fù)的強(qiáng)調(diào)。面向接口編程,實(shí)際上是面向抽象編程,將抽象概念和具體實(shí)現(xiàn)相隔離。這一原則使得我們擁有了更高層次的抽象模型,在面對(duì)不斷變更的需求時(shí),只要抽象模型做的好,修改代碼就要容易的多。但面向接口編程不意味著非得一個(gè)接口對(duì)應(yīng)一個(gè)類(lèi),過(guò)多的不必要的接口也可能帶來(lái)更多的工作量和維護(hù)上的困難。

相比于繼承,OO中多態(tài)的概念要更重要。一個(gè)接口可以對(duì)應(yīng)多個(gè)實(shí)現(xiàn)類(lèi),對(duì)于聲明為接口類(lèi)型的方法參數(shù)、類(lèi)的字段,它們要比實(shí)現(xiàn)類(lèi)更易于擴(kuò)展、穩(wěn)定,這也是多態(tài)的優(yōu)點(diǎn)。假如我以實(shí)現(xiàn)類(lèi)作為方法參數(shù)定義了一個(gè)方法void doSomething(ArrayList list),但如果領(lǐng)導(dǎo)哪天覺(jué)得 ArrayList不如LinkedList更好用,我將不得不將方法重構(gòu)為void doSomething(LinkedList list),相應(yīng)地要在所有調(diào)用此方法的地方修改參數(shù)類(lèi)型(很遺憾地,我連對(duì)象創(chuàng)建也是采用ArrayList list = new ArrayList()方式,這將大大增加我的修改工作量)。如果領(lǐng)導(dǎo)又覺(jué)得用list存儲(chǔ)數(shù)據(jù)不如set好的話,我將再一次重構(gòu)方法,但這一次我變聰明了,我將方法定義為void doSomething(Set set),創(chuàng)建對(duì)象的方式改為Set set = new HashSet()。但這樣仍不夠,如果領(lǐng)導(dǎo)又要求將set改回list怎么辦?所以我應(yīng)該將方法重構(gòu)為void doSomething(Collection collection), Collection的抽象程度***,更易于替換具體的實(shí)現(xiàn)類(lèi)。即便需要List或者Set固有的特性,我也可以做向下類(lèi)型轉(zhuǎn)換解決問(wèn)題,盡管這樣做并不安全。

面向接口編程最重要的價(jià)值在于隱藏實(shí)現(xiàn),將抽象的實(shí)現(xiàn)細(xì)節(jié)封裝起來(lái)而不對(duì)外開(kāi)放,封裝這對(duì)于Java EE 中的分層設(shè)計(jì)和框架設(shè)計(jì)尤其重要。但即便在編程時(shí)使用了接口,我們也需要將接口和實(shí)現(xiàn)對(duì)應(yīng)起來(lái),這就引出如何創(chuàng)建對(duì)象的問(wèn)題。在創(chuàng)建型設(shè)計(jì)模式中,單例、工廠方法(模板方法)、抽象工廠等模式都是很好的解決辦法。現(xiàn)在流行的控制反轉(zhuǎn)(也叫依賴(lài)注入)模式是以聲明的方式將抽象與實(shí)現(xiàn)連接起來(lái),這既減少了單調(diào)的工廠類(lèi)也更易于單元測(cè)試。

做個(gè)總結(jié)吧。盡管我竭力批駁繼承的不好鼓吹接口的好,但這并不是絕對(duì)的。濫用繼承、濫用接口都會(huì)帶來(lái)問(wèn)題。做Java EE開(kāi)發(fā)的很多朋友抱怨DAO、Service中一個(gè)接口一個(gè)類(lèi)的實(shí)現(xiàn)方式,盡管它們似乎看起來(lái)已成為業(yè)界的***實(shí)踐之一。也許排除掉面向接口編程更“瘦”一些,但“瘦”并一定就“好”,需要根據(jù)項(xiàng)目的具體情況而定。關(guān)于繼承和接口的***實(shí)踐,各位看官還是需要自身的經(jīng)驗(yàn)積累和總結(jié)了。

【編輯推薦】

  1. Red Hat CEO呼吁甲骨文繼續(xù)保持Java開(kāi)放
  2. 自學(xué)Javabean迅速成為Java高手
  3. Java通過(guò)JNI調(diào)用C語(yǔ)言的方法
  4. 高手Java核心技術(shù)學(xué)習(xí)筆記
  5. 成為Java高手需要注意的25個(gè)學(xué)習(xí)目標(biāo)
責(zé)任編輯:王觀 來(lái)源: 賽迪網(wǎng)
相關(guān)推薦

2013-07-30 09:42:41

實(shí)現(xiàn)編程接口編程對(duì)象編程

2022-07-30 23:41:53

面向過(guò)程面向?qū)ο?/a>面向協(xié)議編程

2021-01-14 08:16:41

Python接口編程

2011-05-25 10:59:26

Javascript繼承

2010-10-08 09:13:15

oop模式JavaScript

2023-02-22 18:06:35

函數(shù)javascript面向?qū)ο缶幊?/a>

2009-01-04 09:08:30

面向?qū)ο?/a>繼承接口

2009-06-22 11:27:59

反向控制原理面向切面編程Spring

2020-07-23 17:29:47

接口編程代碼

2023-11-07 16:00:25

面向切面編程開(kāi)發(fā)

2015-03-20 09:54:44

網(wǎng)絡(luò)編程面向連接無(wú)連接

2011-07-15 15:47:02

JAVA

2023-09-27 23:28:28

Python編程

2014-06-27 09:10:23

UDPTCP

2023-04-19 08:43:52

Python面向?qū)ο缶幊?/a>

2010-04-26 08:53:06

面向方面編程.NET

2023-10-04 17:25:01

面向接口編程

2009-05-13 11:50:17

C#多繼承接口

2011-05-25 11:15:02

Javascript繼承

2010-06-18 15:15:13

UML
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 欧美美女爱爱 | 久久在看 | 亚洲精品一区二区 | 午夜寂寞影院列表 | 一区二区免费 | 找个黄色片| 亚洲国产精品久久久久久 | 男人天堂免费在线 | 久久精品国产一区 | 国产一区二区成人 | 在线久草| 成人免费区一区二区三区 | 狠狠涩| 日韩欧美在线观看视频网站 | 羞羞网站在线观看 | 欧美6一10sex性hd | 亚洲 欧美 综合 | 中文字幕 亚洲一区 | 欧美成人a∨高清免费观看 色999日韩 | 日韩成人一区二区 | 国产精品激情 | 在线色 | 91资源在线 | 日日操夜夜操天天操 | av在线一区二区三区 | 鲁大师一区影视 | 天天综合国产 | 九九热精品视频 | 精品国产久 | 久久久噜噜噜www成人网 | 亚洲免费视频一区 | 18gay男同69亚洲网站 | 美日韩中文字幕 | 另类视频在线 | 亚洲电影第三页 | 欧美八区| 午夜日韩| 久久中文字幕电影 | 二区中文字幕 | 成人免费看黄网站在线观看 | 欧美大片一区 |