我的理解,父類有的,子類也得有。父類提供了地基,子類繼承地基,繼續(xù)建房子即可,玩玩不可在子類上取破壞父類提供的地基。
為什么叫里氏替換原則?
里氏替換原則在SOLID這五個設(shè)計原則中是比較特殊的存在:
- 如果違反了里氏替換原則,不只是降低軟件設(shè)計的優(yōu)雅性,很可能會導(dǎo)致Bug
- 只有里氏替換原則是以人名命令的
里氏替換原則譯自Liskov substitution principle。Liskov是一位計算機(jī)科學(xué)家,也就是Barbara Liskov,麻省理工學(xué)院教授,也是美國第一個計算機(jī)科學(xué)女博士,師從圖靈獎得主John McCarthy教授,人工智能概念的提出者。
里氏替換原則最初由Barbara Liskov在1987年的一次學(xué)術(shù)會議中提出,而真正正式發(fā)表是在1994年,Barbara Liskov 和 Jeannette Wing發(fā)表的一篇學(xué)術(shù)論文《A behavioral notion of subtyping》.
什么是里氏替換原則?
里氏替換原則在1994年Barbara Liskov 和 Jeannette Wing發(fā)表論文中的描述是:
If S is a declared subtype of T, objects of type S should behave as objects of type T are expected to behave, if they are treated as objects of type T
從字面上翻譯:如果S是T的子類型,對于S類型的任意對象,如果將他們看作是T類型的對象,則對象的行為也理應(yīng)與期望的行為一致。
而另一種關(guān)于里氏替換原則的描述為Robert Martin在《敏捷軟件開發(fā):原則、模式與實踐》一書中對原論文的解讀:子類型(subtype)必須能夠替換掉他們的基類型(base type)。這個是更簡明的一種表述。
如何理解里氏替換原則?
不管是Barbara Liskov論文中的表述,還是Robert Martin的解讀,都是比較抽象的表達(dá)。要理解里氏替換原則,其實就是要理解兩個問題:
- 什么是替換?
- 什么是與期望行為一致的替換(Robert Martin所說的“必須能夠替換”)?
什么是替換
替換的前提是面向?qū)ο笳Z言所支持的多態(tài)特性,同一個行為具有多個不同表現(xiàn)形式或形態(tài)的能力。
什么是與期望行為一致的替換?
在不了解派生類的情況下,僅通過接口或基類的方法,即可清楚的知道方法的行為,而不管哪種派生類的實現(xiàn),都與接口或基類方法的期望行為一致。或者說接口或基類的方法是一種契約,使用方按照這個契約來使用,派生類也按照這個契約來實現(xiàn)。這就是與期望行為一致的替換。
違反里氏替換原則的危害
當(dāng)我們違反了這一原則會帶來有一些危害:
- 反直覺。期望所有子類行為是一致的,但如果不一致可能需要文檔記錄,或者在代碼跑失敗后漲此知識;
- 不可讀。如果子類行為不一致,可能需要不同的邏輯分支來適配不同的行為,徒增代碼復(fù)雜度;
- 不可用。可能出錯的地方終將會出錯。
如何避免違反里氏替換原則
談到如何避免,當(dāng)然要基于里氏替換原則的定義,與期望行為一致的替換
。
- 從行為出發(fā)來設(shè)計。在做抽象或設(shè)計時,不只是要從模型概念出發(fā),還要從行為出發(fā),比如一個經(jīng)典的例子,正方形和長方形,從現(xiàn)實的概念中正方形是一個長方形,但是在計算其面積的行為上是不一致的。
- 基于契約設(shè)計。這個契約即是基類方法簽名、功能描述、參數(shù)類型、返回值等。在派生類的實現(xiàn)時,時刻保持派生類與基類的契約不被破壞。