●定義
子型別必須能夠替換掉它們的基型別。
●關於「is-a」
通常說「is-a」是乙個繼承關係,如果某個將要被建立的類與現存的某個類滿足這種關係,那麼這個新類應該從這個現存中繼承。
「替換原則」告訴我們怎麼樣去使用物件導向三大機制中的「繼承與多型」。c#語言中(很多語言也是這樣的)乙個子類是可以轉換為其基類的,換句話說就是對基類的操作同樣適用於其子類。這一點看上去十分簡單,但在編寫**的時候,我們卻可能會被「is-a」這個基本的物件導向分析方法所誤導,在子類在某些情況下不能夠去替換它們的基類。
「敏捷軟體開發」一書中例舉了乙個很好的例子,就是關於矩形與正方形。從通常的「is-a」關係上來說,正方形就是乙個矩形,因而,我們可以從矩形派生乙個正方形。但隨之問題就來了。這是很明顯的,矩形的長與寬是不一樣的,所以這個類它需要兩個屬性用於設定長與寬;而正方形的長與寬是一樣,所以如果從矩形繼承而來,那麼,有一部分東西是正方形不需要的。這不是本質的問題,本質的問題在於正方形與矩形的操作形為是不一樣的。假設矩形與正方形都是面積的計算方法,在計算矩形面積時,在設定了長與寬之後(如長4寬5)就可以計算出其面積(面積為20),現在我們的類呼叫者就是這樣做的。但如果換成正方形呢?在設定了長與寬後(假設正方形從矩形繼承,並且我們將乙個正方形傳給了呼叫者,呼叫者通過其類來計算其面積)計算其面積時我們就會發現,正方形這個子類是不能夠取代其基類矩形的。為什麼?由於正方形的長與寬相同,所以當你設定了正方形的長度之後,寬度就會相應改變(變為相等),但這種特性不是矩形所擁有的。顯然這不是合適的。
為什麼會產生這種問題?這就是「is-a」所帶來的問題。上面所討論問題的根本之在於「正方形與矩形的行為方式不同」,儘管正方形卻是乙個長寬相等的矩形。「is-a」強調的是行為上的「is-a」,這種形為是外在且公開的。乙個類的行為方式才是設計者真正需要關心的東西,也是呼叫者所需要依賴的東西。所以在繼承時需要慎重考慮,這種考慮並不能完全基於「某個東西是乙個什麼東西」,更重要的是要從其操作行為上分析「某個東西從操作行為上看是乙個什麼東西」,確保子類不會更改其基類的行為方式。
最後,「is-a」是ocp原則得以正確應用的主要原則之一,因為它們都是在子類可以替換基類的情況下進行的。違反liskov替換原則,也會直接或間接的違反ocp原則。
附註:物件導向的三個基本特徵:
物件導向的三個基本特徵是封裝、繼承、和多型。這三個特徵可以使所設計的軟體結構穩定,易維護,可復用性強。
封裝將一組相關操作或屬性封裝到乙個類中,對外只提供了必要的屬性或方法,而具體的實現對外部隱藏。相比面向過程設計中的模組化的復用性更強。
繼承一方面如同我們這一代會擁有父親那一代一些特徵一樣,另一方面又如同我們會有自己獨有的個性特徵相似。在程式世界裡,繼承的乙個重要作用就是對父類功能的擴充套件。
多型則像我們都有父輩的"臉"這個詞,但它表現在我們每個人身上卻是不同形態的(人臉都不同)。在物件導向程式設計裡,就是父類定義的屬性或方法,被不同子類所繼承後可以有不同的特徵或行為。這種多型的實現方式是重寫(重寫父類中的方法)。
從整體來看,封裝和繼承有相同的功能--達到**復用的目的。只不過封裝後可以在任意地方復用整個類的東西,而繼承則是在子類中復用父類中的**(而子類的東西可以在任意地方復用,則又是封裝的作用了)。那麼多型的作用是什麼呢?它要達到的則是介面的復用,這個介面不是物件導向程式設計中的介面型別,而是指在父類或介面型別中定義的方法名稱等。
上面主要提到了這三個特徵的可復用性的作用,而要實現軟體的結構穩定和易維護性則需要三者的協調使用了。也就是與自己的系統架構和每個類的詳細設計有關了。
物件導向設計原則
oo原則 封裝變化 多用組合,少用繼承 針對介面程式設計,不針對實現程式設計 為互動物件之間的松耦合而努力 類應該對擴充套件開放,對修改關閉 依賴抽象,不要依賴具體類 只和朋友交談 別找我,我會找你 類應該只有乙個改變的理由 從設計原則到設計模式 針對介面程式設計,而不是針對實現程式設計 客戶無需知...
物件導向設計原則
物件設計原則 物件導向設計原則 物件導向設計的基石是 開 閉 原則。開一閉 原則講的是 乙個軟體實體應當對擴充套件開放,對修改關閉。這個規則說的是,在設計乙個模組的時候,應當使這個模組可以在不被修改的前提下被擴充套件。從另外乙個角度講,就是所謂的 對可變性封裝原則 對可變性封裝原則 意味著兩點 1 ...
物件導向設計原則
oo原則 封裝變化 多用組合,少用繼承 針對介面程式設計,不針對實現程式設計 為互動物件之間的松耦合而努力 類應該對擴充套件開放,對修改關閉 依賴抽象,不要依賴具體類 只和朋友交談 別找我,我會找你 類應該只有乙個改變的理由 從設計原則到設計模式 針對介面程式設計,而不是針對實現程式設計 客戶無需知...