Udemy課程Design Patterns in Java 3
SOLID Design Principles-(3)Liskov Substitution Principle(LSP)
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內分別設定所需的行為