五大原則之 黎克特制替換原則(LSP)

2022-05-21 02:21:21 字數 1388 閱讀 9353

闡述:子型別(subtype)必須能夠替換掉它們的基型別(basetype)

先提出乙個問題:正方形是不是一種特殊的長方形(is - a關係)?

先不要回答這個問題,看下面的分析。

理解:lsp原則的乙個例子,假如有個people的基類,兩個字類man類和woman類,都繼承於people類。那麼針對people類的任何操作,比如fun吃飯、fun睡覺、fun走路,對於man類和woman類都成立。這個很好理解,不管是man還是woman,歸根結底,還都是乙個people。

(一)正常思維

如下例子:

class cshape

;class ccircle:public cshape

;class csquare:public cshape

;在使用cshape物件的任何地方,都可以使用ccircle物件或者csquare物件。

(二)、特殊情況呢?

回到最初的問題,正方形是不是矩形的問題。

如下類:

class crectangle

;class csquare:public crectangel

;假如有個函式

void g(crectangle * r)

r.width = 4;

r.height = 5;

if( r.area() != 20)

break;

請問,對於函式g來說,能用乙個csquare物件,代替crectangle物件嗎?很明顯,不能!

很明顯,違反了lsp原則。

那麼,正方形到底是不似乎矩形呢?也就是說csquare和crectangle之間,是否存在(is - a)關係呢?

解釋:1、從屬性方面講,正方形是矩形,是一種特殊矩形,即width = height;

2、從行為方式將,正方形可能不是矩形。

比如,對於函式g來說,描述了矩形的一種行為方式,很明顯,正方形不符合這種行為方式。

ood中的is-a關係,

是就行為方式而言的,行為方式是可以進行合理假設的。而行為方式,才是我們進行物件導向軟體設計真正所關注的問題。

因此,可以講,正方形不是乙個矩形

(三)、怎麼處理此類問題呢?

1、基於契約進行設計。

每個類設計時,都會有一些假設,每個方法,都有前置條件,後置條件,這些條件都是契約。對這些方法,要註明契約。

要想從基類派生子類,就必須滿足這些契約。如果不滿足這些契約,就不能繼承出子類。(即使他們看起來很像,比如正方形與矩形)

2、但是我們又需要lsp原則,怎麼辦呢?

從crectangle類和csquare類,提取出公共部分,做為乙個基類。比如cshape類。

crectangle和csquare都繼承自cshape類。

設計模式之六大原則 黎克特制替換原則(LSP)

黎克特制替換原則 liskov substitution principel 是解決繼承帶來的問題。繼承的優點 繼承的缺點 定義 所有引用基類的地方必須能透明地使用其子類的物件。通俗點講,只要父類能出現的地方子類就可以出現,而且替換為子類也不會產生任何錯誤或異常,使用者可能根本就不需要知道是父類還是...

設計模式之六大原則 黎克特制替換原則(LSP)

黎克特制替換原則 liskov substitution principel 是解決繼承帶來的問題。繼承的優點 繼承的缺點 定義 所有引用基類的地方必須能透明地使用其子類的物件。通俗點講,只要父類能出現的地方子類就可以出現,而且替換為子類也不會產生任何錯誤或異常,使用者可能根本就不需要知道是父類還是...

PHP物件導向五大原則之黎克特制替換原則 LSP 詳解

替換原則由mit電腦科學實驗室的liskov女士在1987年的oopsla大會上的一篇文章中提出,主要闡述有關繼承的一些原則,故稱黎克特制替換原則。2002年,robert c.martin出版了一本名為 agile software development principles patterns ...