Udemy課程Design Patterns in Java 3

SOLID Design Principles-(3)Liskov Substitution Principle(LSP)

ZONGRU Li
3 min readJul 23, 2019

Liskov Substitution Principle(LSP):里氏替換原則

解釋:

當實作是繼承了Interface或Base-class的子類別

不論子類別做任何設定

都不應影響Interface或Base-class本身功能的結果

先做出一個Base-class(父類)-Rectangle(矩形)

Rectangle其中有提供一個面積計算功能,回傳寬*高的值

然後再建了一個子類-Square(方形)去擴展Rectangle

Square乍看沒什麼問題,程式邏輯就是個方形該有的

但是Square已然違反LSP

接著證明Square違反LSP,製做DemoLSP

執行起來也沒什麼問題

接著連Square實例也實作

執行結果:

結果的100已經偏離我們預期值50了

其原因是因為useIt內的r.setHeight(10);

由於已經透過int width =r.getWidth();

將width(寬)提出5這個數字,但是當r.setHeight(10);執行後

square內的寬跟高都變成10、10

所以width*10=5*10,這邊的width已於square內的width不同!

然後r.getArea()=10*10

(可以花一點時間理解程式執行順序)

主要根因是Square的覆寫父類方法的等邊長行為

已經違反父類Rectangle特性的不變性

就一般概念下Square當然屬於Rectangle

但是在此場景下,是要依

行為(ex:Method)

來決定

由於繼承的高偶合性,更應該考慮子類 override內容是否符合父類

且由上面例子可以看到,在違反LSP下會出現極不明顯的bug

在此講師是建議兩種做法

1.Square就乾脆不必存在

然後在DemoLSP內單純建立個確認是否是square就好

2.若真的很需要各自建立Rectangle跟Square,那麼可以考慮使用

Factory Pattern

在一個工廠class內分別設定所需的行為

--

--

ZONGRU Li
ZONGRU Li

Written by ZONGRU Li

2022/11/17 開源部分個人筆記給LINE "Java程式語言討論區"社群,希望能對社群的技術學習做一點點貢獻.(掩面....記得退訂閱!

No responses yet