【java基礎(三十五)】繼承的設計技巧

將公共操作和域放在超類

這就是爲什麼將姓名域放在Person類中,而沒有將它放在Employee和Student類中的原因。

不要使用受保護的域

有些程序員認爲,將大多數的實例域定義爲protected是一個不錯的主意,只有這樣,子類才能夠在需要的時候直接訪問它們。然而,protected機制並不能夠帶來更好的保護,其原因主要有兩點:第一,子類集合是無限制的,任何一個人都能夠由某個類派生一個子類,並編寫代碼以直接訪問protected的實例域,從而破壞了封裝性。第二,在Java程序設計語言中,在同一個包中的所有類都可以訪問protected域,而不管它是否爲這個類的子類。
不過,protected方法對於指示那些不提供一般用途而應在子類中重新定義的方法很有用。

使用繼承實現“is - a”關係

使用繼承很容易達到節省代碼的目的,但有時候也被人們濫用了。例如,假設需要定義一個鐘點工類。鐘點工的信息包含姓名和僱傭日期,但是沒有薪水。他們按小時計薪,並且不會因爲拖延時間而獲得加薪。這似乎在誘導人們由Employee派生出子類Contractor,然後再增加一個hourlyWage域。
這並不是一個好主意。因爲這樣一來,每個鐘點工對象中都包含了薪水和計時工資這兩個域。在實現打印支票或稅單方法的時候,會帶來無盡的麻煩,並且與不採用繼承,會多寫很多代碼。
鐘點工與僱員之間不屬於“is - a”關係,鐘點工不是特殊的僱員。

除非所有繼承的方法都有意義,否則不要使用繼承

假設想編寫一個Holiday類。毫無疑問,每個假日也是一日,並且一日可以用GregorianCalendar類的實例表示,因此可以使用繼承:

class Holiday extends GregorianCalendar{...}

但是很遺憾,在繼承的操作中,假日類不是封閉的。在GregorianCalendar中有一個共有方法add,可以將假日轉換成非假日,因此,繼承對於這個例子並不太合適。

在覆蓋方法時,不要改變預期的行爲

覆蓋方法時,覆蓋的方法實現是可以隨意實現的,但,在覆蓋子類中的方法時,不要偏離最初的設計想法,否則你對這個方法的實現有什麼意義呢?

使用多態,而非類型信息

無論什麼時候,對於下面這種形式的代碼

if (x is of type1)
	action1(x);
else if (x is of type2)
	action2(x);

都應該考慮使用多態性。

action1與action2表示的是相同的概念嗎?如果是相同的概念,就應該爲這個概念定義一個方法,並將其放置在兩個類的超類或接口中,然後,就可以調用x.action(),以便使用多態性提供的動態分配機制執行相應的動作。

使用多態方法或接口編寫的代碼比使用多種類型進行檢測的代碼更加易於維護和擴展。

不要過多的使用反射

反射機制使得人們可以通過在運行時查看域和方法,讓人們編寫出更具有通用性的程序。這種功能對於編寫系統程序來說極其實用,但是通常不適於編寫應用程序。反射是很脆弱的,即編譯器很難幫助人們發現程序中的錯誤,因此只有在運行時才發現錯誤並導致異常。

捐贈

若你感覺讀到這篇文章對你有啓發,能引起你的思考。請不要吝嗇你的錢包,你的任何打賞或者捐贈都是對我莫大的鼓勵。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章