首頁 > 常見問題 > 里氏替換原則是什麼?

里氏替換原則是什麼?

青灯夜游
發布: 2020-07-28 12:01:12
原創
6273 人瀏覽過

里氏替換原則是物件導向設計的基本原則之一,主張使用「抽象(Abstraction)」和「多態(Polymorphism)」將設計中的靜態結構改為動態結構,維持設計的封閉性。 「抽象」是語言提供的功能,「多態」由繼承語意實現。

里氏替換原則是什麼?

里氏替換原則(Liskov Substitution Principle,LSP)由麻省理工學院電腦科學實驗室的里斯科夫(Liskov)女士在1987 年的「物件導向技術的高峰會議」(OOPSLA)上發表的一篇文章《資料抽象與層次》(Data Abstraction and Hierarchy)裡提出來的,她提出:繼承必須確保超類別所擁有的性質在子類別中仍然成立(Inheritance should ensure that any property proved about supertype objects also holds for subtype objects)。

里氏替換原則主要闡述了有關繼承的一些原則,也就是什麼時候應該使用繼承,什麼時候不應該使用繼承,以及其中蘊含的原理。里氏替換原是繼承復用的基礎,它反映了基底類別與子類別之間的關係,是對開閉原則的補充,是實現抽象化的具體步驟的規範。

里氏替換原則的作用

里氏替換原則的主要作用如下。

1、里氏替換原則是實現開閉原則的重要方式之一。

2、它克服了繼承中重寫父類別造成的可重複使用性變差的缺點。

3、它是動作正確性的保證。即類別的擴充不會為現有的系統引入新的錯誤,降低了程式碼出錯的可能性。

里氏替換原則的實作方法

里氏替換原則通俗來講就是:子類別可以擴充父類別的功能,但不能改變父類別原有的功能。也就是說:子類別繼承父類別時,除新增新的方法完成新增功能外,盡量不要重寫父類別的方法。

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

如果程式違反了里氏替換原則,則繼承類別的物件在基底類別出現的地方會出現運行錯誤。這時其修正方法是:取消原來的繼承關係,重新設計它們之間的關係。

關於里氏替換原則的例子,最有名的是「正方形不是長方形」。當然,生活中也有很多類似的例子,例如,企鵝、鴕鳥和幾維鳥從生物學的角度來劃分,它們屬於鳥類;但從類的繼承關係來看,由於它們不能繼承“鳥”會飛的功能,所以它們不能定義成「鳥」的子類。同樣,由於「氣球魚」不會游泳,所以不能定義成「魚」的子類;「玩具炮」炸不了敵人,所以不能定義成「砲」的子類等。

以下以「幾維鳥不是鳥」為例來說明里氏替換原則。

【例2】里氏替換原則在「幾維鳥不是鳥」實例中的應用。

分析:鳥一般都會飛行,如燕子的飛行速度大概是每小時 120 公里。但是紐西蘭的幾維鳥由於翅膀退化而無法飛行。如果要設計一個實例,計算這兩種鳥飛行 300 公里要花費的時間。顯然,拿燕子來測試這段程式碼,結果正確,能計算出所需的時間;但拿幾維鳥來測試,結果會發生“除零異常”或“無窮大”,明顯不符合預期,其類圖如圖1 所示。

里氏替換原則是什麼?

程式碼如下:

package principle;
public class LSPtest
{
    public static void main(String[] args)
    {
        Bird bird1=new Swallow();
        Bird bird2=new BrownKiwi();
        bird1.setSpeed(120);
        bird2.setSpeed(120);
        System.out.println("如果飞行300公里:");
        try
        {
            System.out.println("燕子将飞行"+bird1.getFlyTime(300)+"小时.");
            System.out.println("几维鸟将飞行"+bird2.getFlyTime(300)+"小时。");
        }
        catch(Exception err)
        {
            System.out.println("发生错误了!");
        }
    }
}
//鸟类
class Bird
{
    double flySpeed;
    public void setSpeed(double speed)
    {
        flySpeed=speed;
    }
    public double getFlyTime(double distance)
    {
        return(distance/flySpeed);
    }
}
//燕子类
class Swallow extends Bird{}
//几维鸟类
class BrownKiwi extends Bird
{
    public void setSpeed(double speed)
    {
           flySpeed=0;
    }
}
登入後複製

程式的運行結果如下:

如果飞行300公里:
燕子将飞行2.5小时.
几维鸟将飞行Infinity小时。
登入後複製

程式執行錯誤的原因是:幾維鳥類重寫了鳥類的setSpeed(double speed) 方法,違反了里氏替換原則。正確的做法是:取消幾維鳥原來的繼承關係,定義鳥和幾維鳥的更一般的父類,如動物類,它們都有奔跑的能力。幾維鳥的飛行速度雖然為 0,但奔跑速度不為 0,可以計算出其奔跑 300 公里所需的時間。

其類別圖如圖 2 所示。

里氏替換原則是什麼?

更多相關知識,請造訪:PHP中文網

以上是里氏替換原則是什麼?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板