-
將公共操作和字段放在超類
這就是為什么將姓名字段放在 Person 類中,而沒(méi)有將它放在 Employee 和 Student類中的原因愚战。
-
不要使用受保護(hù)的字段
有些程序員認(rèn)為,將大多數(shù)的實(shí)例字段定義為 protected 是一個(gè)不錯(cuò)的主意齐遵,“以防萬(wàn)一”寂玲,這樣子類能夠在需要的時(shí)候直接訪問(wèn)這些字段。然而梗摇,protected 機(jī)制并不能夠帶來(lái)更多的保護(hù)拓哟,這有兩方面的原因:
1. 子類集合是無(wú)限制的,任何一個(gè)人都能夠由你的類派生一個(gè)子類伶授,然后編寫(xiě)代碼以直接訪問(wèn) protected 實(shí)例字段断序,從而破壞了封裝性。
1. 在 Java 中糜烹,在同一個(gè)包中的所有類都可以訪問(wèn) proteced 字段违诗,而不管它們是否為這個(gè)類的子類。不過(guò)疮蹦,protected 方法對(duì)于指示那些不提供一般用途而應(yīng)在子類中重新定義的方法很有用诸迟。
-
使用繼承實(shí)現(xiàn) “is-a” 關(guān)系
使用繼承很容易達(dá)到節(jié)省代碼的目的,但有時(shí)候也被人們?yōu)E用。例如阵苇,假設(shè)需要定義一個(gè)鐘點(diǎn)工(Contractor)類壁公。鐘點(diǎn)工有姓名和雇傭日期,但是沒(méi)有工資绅项。他們按小時(shí)計(jì)薪紊册,并且不會(huì)因?yàn)橥涎訒r(shí)間而獲得加薪。這似乎在誘導(dǎo)人們由 Employee 派生出子類 Contractor快耿,然后再增加一個(gè) hourlyWage 字段囊陡。
public class Contractor extends Employee {
?private double hourlyWage;
?...
}
不過(guò),這并不是一個(gè)好主意润努。因?yàn)檫@樣一來(lái)关斜,每個(gè)鐘點(diǎn)對(duì)象中都包含了工資和時(shí)薪這兩個(gè)字段。在實(shí)現(xiàn)打印時(shí)薪或稅單的方法時(shí)铺浇,這會(huì)帶來(lái)無(wú)盡的麻煩痢畜,與不采用繼承相比,使用繼承實(shí)現(xiàn)最后反而會(huì)寫(xiě)多寫(xiě)很多代碼鳍侣。
鐘點(diǎn)工與員工之間不屬于“ is-a” 關(guān)系丁稀。鐘點(diǎn)工不是特殊的員工。
-
除非所有繼承的方法都有意義倚聚,否則不要使用繼承
假設(shè)想編寫(xiě)一個(gè) Holiday 類线衫。毫無(wú)疑問(wèn),每個(gè)假日也是一日惑折,并且一天可以用 GregorianCalendar 類的實(shí)例表示授账,因此可以使用繼承。
class Holiday extends CregorianCalendar { . . .}
很遺憾惨驶,在繼承的操作中白热,假日集合不是封閉的。在 GregorianCalendar 中有一個(gè)公有方法 add粗卜,可以將假日轉(zhuǎn)換成非假日:
Holiday Christmas;
Christmas.add(Calendar.DAY_OF_MONTH, 12);
因此屋确,繼承對(duì)于這個(gè)例子來(lái)說(shuō)并不太適宜。
需要指出续扔,如果擴(kuò)展 LocalDate 就不會(huì)出現(xiàn)這個(gè)問(wèn)題攻臀。由于這個(gè) LocalDate 類是不可變的,所以沒(méi)有任何方法能夠把假日變成非假日纱昧。 -
在覆蓋方法時(shí)刨啸,不要改變預(yù)期的行為
替換原則不僅應(yīng)用于語(yǔ)法,更重要的是识脆,它也適用于行為设联。在覆蓋一個(gè)方法的時(shí)候加匈,不應(yīng)該毫無(wú)原由地改變它的行為。就這一點(diǎn)而言仑荐,編譯器不會(huì)提供任何幫助,即編譯器不會(huì)檢查重新定義的方法是否有意義纵东。例如粘招,可以重新定義 Holiday 類中的 add 方法來(lái)“修正”這個(gè)方法的問(wèn)題,可能什么也不做偎球,或者拋出一個(gè)異常洒扎,或者是前進(jìn)到下一個(gè)假日。
然而衰絮,這樣一個(gè)“修正”違反了替換原則袍冷。對(duì)于以下語(yǔ)句序列
int d1 = x.get(Calendar.DAY_OF_MONTH);
x.add(Calendar.DAY_OF_MONTH, 1);
int d2 = x.get(Calendar.DAY_OF_MONTH);
System.out.println(d2 - d1);
不管 x 的類型是 CregorianCalendar 還是 Holiday,執(zhí)行上述語(yǔ)句后都應(yīng)該得到預(yù)期行為猫牡。當(dāng)然胡诗,這個(gè)難題。理智和不理智的人們可能就預(yù)期行為是什么爭(zhēng)論不休淌友。煌恢。例如,有些人爭(zhēng)論說(shuō)震庭,置換原則要求 Manager.equals 忽略 bonus 字段瑰抵,因?yàn)?Employee.equals 就忽略了這個(gè)字段。實(shí)際上器联,憑空討論這些問(wèn)題毫無(wú)意義二汛。歸根結(jié)底,關(guān)鍵在于在子類中覆蓋方法時(shí)拨拓,不要偏離最初的設(shè)計(jì)想法肴颊。
-
使用多態(tài),而不要使用類型信息
只要看到類似下面的代碼
if(x is of type 1) {
?action1(x);
}else if(x is of type 2) {
?action2(x);
}
都應(yīng)該考慮使用多態(tài)性千元。
action1 與 action2 表示的是相同的概念嗎苫昌?如果是相同的概念,就應(yīng)該為這個(gè)概念定義一個(gè)方法幸海,并將其放置在兩個(gè)類型的超類或接口中祟身,然后,就可以調(diào)用
x.action();
使用多態(tài)性固有的動(dòng)態(tài)分派機(jī)制執(zhí)行正確的動(dòng)作物独。使用多態(tài)方法或接口實(shí)現(xiàn)的代碼比使用多個(gè)類型檢測(cè)的代碼更易于維護(hù)和擴(kuò)展袜硫。
-
不要濫用反射
反射機(jī)制使人們可以在運(yùn)行時(shí)查看字段和方法,從而編寫(xiě)出更具有通用性的程序挡篓。這種功能對(duì)于編寫(xiě)系統(tǒng)程序及其重要婉陷,但是通常不適用于編寫(xiě)應(yīng)用程序帚称。反射是很脆弱的,如果使用反射秽澳,編譯器將無(wú)法幫助你查找編程錯(cuò)誤闯睹,因此只有在運(yùn)行時(shí)才會(huì)發(fā)現(xiàn)錯(cuò)誤并導(dǎo)致異常。
繼承的設(shè)計(jì)技巧(學(xué)習(xí) Java 編程語(yǔ)言 055)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
- 文/潘曉璐 我一進(jìn)店門炕置,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)荣挨,“玉大人,你說(shuō)我怎么就攤上這事讹俊】殉粒” “怎么了?”我有些...
- 文/不壞的土叔 我叫張陵仍劈,是天一觀的道長(zhǎng)厕倍。 經(jīng)常有香客問(wèn)我,道長(zhǎng)贩疙,這世上最難降的妖魔是什么讹弯? 我笑而不...
- 正文 為了忘掉前任,我火速辦了婚禮这溅,結(jié)果婚禮上组民,老公的妹妹穿的比我還像新娘。我一直安慰自己悲靴,他們只是感情好臭胜,可當(dāng)我...
- 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著癞尚,像睡著了一般耸三。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上浇揩,一...
- 那天仪壮,我揣著相機(jī)與錄音,去河邊找鬼胳徽。 笑死积锅,一個(gè)胖子當(dāng)著我的面吹牛爽彤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播缚陷,決...
- 文/蒼蘭香墨 我猛地睜開(kāi)眼适篙,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了箫爷?” 一聲冷哼從身側(cè)響起匙瘪,我...
- 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蝶缀,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體薄货,經(jīng)...
- 正文 獨(dú)居荒郊野嶺守林人離奇死亡翁都,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
- 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了谅猾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片柄慰。...
- 正文 年R本政府宣布概行,位于F島的核電站,受9級(jí)特大地震影響弧岳,放射性物質(zhì)發(fā)生泄漏凳忙。R本人自食惡果不足惜,卻給世界環(huán)境...
- 文/蒙蒙 一禽炬、第九天 我趴在偏房一處隱蔽的房頂上張望涧卵。 院中可真熱鬧,春花似錦腹尖、人聲如沸柳恐。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)乐设。三九已至,卻和暖如春断凶,著一層夾襖步出監(jiān)牢的瞬間伤提,已是汗流浹背。 一陣腳步聲響...
- 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像舶沛,于是被迫代替她去往敵國(guó)和親嘹承。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
推薦閱讀更多精彩內(nèi)容
- 1如庭、繼承 繼承就是在已經(jīng)存在的類的基礎(chǔ)上再進(jìn)行擴(kuò)展叹卷,從而產(chǎn)生新的類。已經(jīng)存在的類稱為父類坪它、超類或基類骤竹,而新產(chǎn)生的類...
- 1. 多態(tài) 一個(gè)對(duì)象變量可以指示多種實(shí)際類型的現(xiàn)象被稱為多態(tài)(polymorphism)。多態(tài)是同一個(gè)行為具有多個(gè)...
- 如果將一個(gè)類聲明為 abstract往毡,那么這個(gè)類就是抽象類蒙揣。抽象類可以包含抽象方法、字段和具體方法开瞭。抽象類不能被實(shí)...
- 一懒震、類設(shè)計(jì)的技巧 我們?cè)谠O(shè)計(jì)類的時(shí)候,就像在室內(nèi)設(shè)計(jì)一樣嗤详,怎么合理創(chuàng)建每個(gè)變量个扰,并安排每個(gè)方法,是非常重要的葱色。一方...
- 將一個(gè)類型強(qiáng)制轉(zhuǎn)換成另外一個(gè)類型的過(guò)程被稱為強(qiáng)制類型轉(zhuǎn)換递宅。Java 程序設(shè)計(jì)語(yǔ)言提供了一種專門用于進(jìn)行強(qiáng)制類型轉(zhuǎn)換...