首頁技術(shù)文章正文

里氏代換原則是什么?里氏代換原則介紹

更新時(shí)間:2021-08-19 來源:黑馬程序員 瀏覽量:

在軟件開發(fā)中,為了提高軟件系統(tǒng)的可維護(hù)性和可復(fù)用性,增加軟件的可擴(kuò)展性和靈活性,程序員要盡量根據(jù)6條原則來開發(fā)程序,從而提高軟件開發(fā)效率、節(jié)約軟件開發(fā)成本和維護(hù)成本。這六條分別是開閉原則、里氏代換原則、依賴倒轉(zhuǎn)原則、接口隔離原則、迪米特法則、合成復(fù)用原則,下面主要介紹里氏代換原則。

里氏代換原則是面向?qū)ο笤O(shè)計(jì)的基本原則之一。

里氏代換原則:任何基類可以出現(xiàn)的地方,子類一定可以出現(xiàn)。通俗理解:子類可以擴(kuò)展父類的功能,但不能改變父類原有的功能。換句話說,子類繼承父類時(shí),除添加新的方法完成新增功能外,盡量不要重寫父類的方法。

如果通過重寫父類的方法來完成新的功能,這樣寫起來雖然簡(jiǎn)單,但是整個(gè)繼承體系的可復(fù)用性會(huì)比較差,特別是運(yùn)用多態(tài)比較頻繁時(shí),程序運(yùn)行出錯(cuò)的概率會(huì)非常大。

下面看一個(gè)里氏替換原則中經(jīng)典的一個(gè)例子

【例】正方形不是長(zhǎng)方形。

在數(shù)學(xué)領(lǐng)域里,正方形毫無疑問是長(zhǎng)方形,它是一個(gè)長(zhǎng)寬相等的長(zhǎng)方形。所以,我們開發(fā)的一個(gè)與幾何圖形相關(guān)的軟件系統(tǒng),就可以順理成章的讓正方形繼承自長(zhǎng)方形。

里氏代換原則

代碼如下:

長(zhǎng)方形類(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):

由于正方形的長(zhǎng)和寬相同,所以在方法setLength和setWidth中,對(duì)長(zhǎng)度和寬度都需要賦相同值。

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是我們的軟件系統(tǒng)中的一個(gè)組件,它有一個(gè)resize方法依賴基類Rectangle,resize方法是RectandleDemo類中的一個(gè)方法,用來實(shí)現(xiàn)寬度逐漸增長(zhǎng)的效果。

public class RectangleDemo {
    
    public static void resize(Rectangle rectangle) {
        while (rectangle.getWidth() <= rectangle.getLength()) {
            rectangle.setWidth(rectangle.getWidth() + 1);
        }
    }

    //打印長(zhǎng)方形的長(zhǎng)和寬
    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);
    }
}

我們運(yùn)行一下這段代碼就會(huì)發(fā)現(xiàn),假如我們把一個(gè)普通長(zhǎng)方形作為參數(shù)傳入resize方法,就會(huì)看到長(zhǎng)方形寬度逐漸增長(zhǎng)的效果,當(dāng)寬度大于長(zhǎng)度,代碼就會(huì)停止,這種行為的結(jié)果符合我們的預(yù)期;假如我們?cè)侔岩粋€(gè)正方形作為參數(shù)傳入resize方法后,就會(huì)看到正方形的寬度和長(zhǎng)度都在不斷增長(zhǎng),代碼會(huì)一直運(yùn)行下去,直至系統(tǒng)產(chǎn)生溢出錯(cuò)誤。所以,普通的長(zhǎng)方形是適合這段代碼的,正方形不適合。 我們得出結(jié)論:在resize方法中,Rectangle類型的參數(shù)是不能被Square類型的參數(shù)所代替,如果進(jìn)行了替換就得不到預(yù)期結(jié)果。因此,Square類和Rectangle類之間的繼承關(guān)系違反了里氏代換原則,它們之間的繼承關(guān)系不成立,正方形不是長(zhǎng)方形。

如何改進(jìn)呢?此時(shí)我們需要重新設(shè)計(jì)他們之間的關(guān)系。抽象出來一個(gè)四邊形接口(Quadrilateral),讓Rectangle類和Square類實(shí)現(xiàn)Quadrilateral接口。

里氏代換原則



猜你喜歡:

MySQL和Oracle的區(qū)別

CentOS 下安裝oracle數(shù)據(jù)庫圖文教程

Java swing是什么?有什么作用?

Java集合的分類有哪些?

黑馬程序員java開發(fā)培訓(xùn)課程

分享到:
在線咨詢 我要報(bào)名
和我們?cè)诰€交談!