黎克特制替換原則

2021-10-18 04:01:37 字數 2904 閱讀 2128

黎克特制代換原則是物件導向設計的基本原則之一。

黎克特制代換原則:任何基類可以出現的地方,子類一定可以出現。通俗理解:子類可以擴充套件父類的功能,但不能改變父類原有的功能。換句話說,子類繼承父類時,除新增新的方法完成新增功能外,盡量不要重寫父類的方法。

如果通過重寫父類的方法來完成新的功能,這樣寫起來雖然簡單,但是整個繼承體系的可復用性會比較差,特別是運用多型比較頻繁時,程式執行出錯的概率會非常大。

下面是乙個違背黎克特制替換原則的經典例子。

在數學領域裡,正方形毫無疑問是長方形,它是乙個長寬相等的長方形。所以,我們開發乙個與幾何圖形相關的軟體系統,就可以順理成章的讓正方形繼承自長方形。

長方形類(rectangle):

public

class

rectangle

public

void

setlength

(double length)

public

double

getwidth()

public

void

setwidth

(double width)

}

正方形類(square):由於正方形的長和寬相同,所以在方法setlength和setwidth中,對長度和寬度都需要賦相同值。

public

class

square

extends

rectangle

// 重寫父類方法,它會帶來惡果

public

void

setlength

(double length)

}

類rectangledemo:它是我們的軟體系統中的乙個元件,它有乙個resize方法依賴基類rectangle,resize方法是rectandledemo類中的乙個方法,用來實現寬度逐漸增長的效果。

public

class

rectangledemo

}//列印長方形的長和寬

public

static

void

printlengthandwidth

(rectangle rectangle)

public

static

void

main

(string[

] args)

}

執行一下這段**。

假如我們把乙個普通長方形作為引數傳入resize方法,就會看到長方形寬度逐漸增長的效果,當寬度大於長度,**就會停止,這種行為的結果符合我們的預期。

假如我們再把乙個正方形作為引數傳入resize方法後,就會看到正方形的寬度和長度都在不斷增長,**會一直執行下去,直至系統產生溢位錯誤。

所以,普通的長方形是適合這段**的,正方形不適合。

從上面的反例中我們可以得出這樣的結論:在resize方法中,rectangle型別的引數是不能被square型別的引數所代替,如果進行了替換就得不到預期結果。因此,square類和rectangle類之間的繼承關係違反了黎克特制代換原則,它們之間的繼承關係不成立,正方形並不是長方形。

如何改進呢?此時我們需要重新設計他們之間的關係。抽象出來乙個四邊形介面(quadrilateral),讓rectangle類和square類實現quadrilateral介面

// 擴寬的方法

public

static

void

resize

(rectangle rectangle)

}// 列印長和寬

public

static

void

printlengthandwidth

(quadrilateral quadrilateral)

}

20.0

21.0

黎克特制替換原則

黎克特制替換原則 黎克特制代換原則 liskov substitution principle lsp 物件導向設計的基本原則之一。黎克特制代換原則中說,任何基類可以出現的地方,子類一定可以出現。lsp是繼承復用的基石,只有當衍生類可以替換掉基類,軟體單位的功能不受到影響時,基類才能真正被復用,而衍...

黎克特制替換原則

黎克特制替換原則更多的說的是子類與父類的關係的一種原則,子類必須實現父類的所有方法,所有能夠放子類的地方一定能夠放父類。但是這裡的話,我們講有的時候在我們的業務中,有的子類肯定是有個性化的特徵的,比如真槍和玩具槍,真槍能射出子彈,但是玩具槍就不能,那麼這個時候,我們或者通過抽象類,通過抽象類是我們可...

黎克特制替換原則

黎克特制替換原則,主要是乙個關於繼承的規範原則,它要求我們在軟體中寫繼承關係時,所有引用父類的地方必須能夠 透 明地使用其子類物件 子類可以實現父類所提供的抽象 方法,但不要去重寫父類已經實現的方法,或者過載父類的 構 造。要維護繼承的傳遞性,當然很多地方為這個原則打了個 比喻為 龍生龍,鳳生鳳,老...