更新時間:2021-08-19 來源:黑馬程序員 瀏覽量:
在軟件開發中,為了提高軟件系統的可維護性和可復用性,增加軟件的可擴展性和靈活性,程序員要盡量根據6條原則來開發程序,從而提高軟件開發效率、節約軟件開發成本和維護成本。這六條分別是開閉原則、里氏代換原則、依賴倒轉原則、接口隔離原則、迪米特法則、合成復用原則,下面主要介紹里氏代換原則。
里氏代換原則是面向對象設計的基本原則之一。
里氏代換原則:任何基類可以出現的地方,子類一定可以出現。通俗理解:子類可以擴展父類的功能,但不能改變父類原有的功能。換句話說,子類繼承父類時,除添加新的方法完成新增功能外,盡量不要重寫父類的方法。
如果通過重寫父類的方法來完成新的功能,這樣寫起來雖然簡單,但是整個繼承體系的可復用性會比較差,特別是運用多態比較頻繁時,程序運行出錯的概率會非常大。
下面看一個里氏替換原則中經典的一個例子
【例】正方形不是長方形。
在數學領域里,正方形毫無疑問是長方形,它是一個長寬相等的長方形。所以,我們開發的一個與幾何圖形相關的軟件系統,就可以順理成章的讓正方形繼承自長方形。
代碼如下:
長方形類(Rectangle):
public class Rectangle { private double length; private double width; public double getLength() { return length; } public void setLength(double length) { this.length = length; } public double getWidth() { return width; } public void setWidth(double width) { this.width = width; } }
正方形(Square):
由于正方形的長和寬相同,所以在方法setLength和setWidth中,對長度和寬度都需要賦相同值。
public class Square extends Rectangle { public void setWidth(double width) { super.setLength(width); super.setWidth(width); } public void setLength(double length) { super.setLength(length); super.setWidth(length); } }
類RectangleDemo是我們的軟件系統中的一個組件,它有一個resize方法依賴基類Rectangle,resize方法是RectandleDemo類中的一個方法,用來實現寬度逐漸增長的效果。
public class RectangleDemo { public static void resize(Rectangle rectangle) { while (rectangle.getWidth() <= rectangle.getLength()) { rectangle.setWidth(rectangle.getWidth() + 1); } } //打印長方形的長和寬 public static void printLengthAndWidth(Rectangle rectangle) { System.out.println(rectangle.getLength()); System.out.println(rectangle.getWidth()); } public static void main(String[] args) { Rectangle rectangle = new Rectangle(); rectangle.setLength(20); rectangle.setWidth(10); resize(rectangle); printLengthAndWidth(rectangle); System.out.println("============"); Rectangle rectangle1 = new Square(); rectangle1.setLength(10); resize(rectangle1); printLengthAndWidth(rectangle1); } }
我們運行一下這段代碼就會發現,假如我們把一個普通長方形作為參數傳入resize方法,就會看到長方形寬度逐漸增長的效果,當寬度大于長度,代碼就會停止,這種行為的結果符合我們的預期;假如我們再把一個正方形作為參數傳入resize方法后,就會看到正方形的寬度和長度都在不斷增長,代碼會一直運行下去,直至系統產生溢出錯誤。所以,普通的長方形是適合這段代碼的,正方形不適合。 我們得出結論:在resize方法中,Rectangle類型的參數是不能被Square類型的參數所代替,如果進行了替換就得不到預期結果。因此,Square類和Rectangle類之間的繼承關系違反了里氏代換原則,它們之間的繼承關系不成立,正方形不是長方形。
如何改進呢?此時我們需要重新設計他們之間的關系。抽象出來一個四邊形接口(Quadrilateral),讓Rectangle類和Square類實現Quadrilateral接口。
猜你喜歡: