您好,登錄后才能下訂單哦!
這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)碛嘘P(guān)什么是里氏替換原則,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
里氏替換原則是面向?qū)ο笤O(shè)計(jì)的基本原則之一,主張使用“抽象(Abstraction)”和“多態(tài)(Polymorphism)”將設(shè)計(jì)中的靜態(tài)結(jié)構(gòu)改為動(dòng)態(tài)結(jié)構(gòu),維持設(shè)計(jì)的封閉性。“抽象”是語言提供的功能,“多態(tài)”由繼承語義實(shí)現(xiàn)。
里氏替換原則(Liskov Substitution Principle,LSP)由麻省理工學(xué)院計(jì)算機(jī)科學(xué)實(shí)驗(yàn)室的里斯科夫(Liskov)女士在 1987 年的“面向?qū)ο蠹夹g(shù)的高峰會(huì)議”(OOPSLA)上發(fā)表的一篇文章《數(shù)據(jù)抽象和層次》(Data Abstraction and Hierarchy)里提出來的,她提出:繼承必須確保超類所擁有的性質(zhì)在子類中仍然成立(Inheritance should ensure that any property proved about supertype objects also holds for subtype objects)。
里氏替換原則主要闡述了有關(guān)繼承的一些原則,也就是什么時(shí)候應(yīng)該使用繼承,什么時(shí)候不應(yīng)該使用繼承,以及其中蘊(yùn)含的原理。里氏替換原是繼承復(fù)用的基礎(chǔ),它反映了基類與子類之間的關(guān)系,是對(duì)開閉原則的補(bǔ)充,是對(duì)實(shí)現(xiàn)抽象化的具體步驟的規(guī)范。
里氏替換原則的作用
里氏替換原則的主要作用如下。
1、里氏替換原則是實(shí)現(xiàn)開閉原則的重要方式之一。
2、它克服了繼承中重寫父類造成的可復(fù)用性變差的缺點(diǎn)。
3、它是動(dòng)作正確性的保證。即類的擴(kuò)展不會(huì)給已有的系統(tǒng)引入新的錯(cuò)誤,降低了代碼出錯(cuò)的可能性。
里氏替換原則的實(shí)現(xiàn)方法
里氏替換原則通俗來講就是:子類可以擴(kuò)展父類的功能,但不能改變父類原有的功能。也就是說:子類繼承父類時(shí),除添加新的方法完成新增功能外,盡量不要重寫父類的方法。
如果通過重寫父類的方法來完成新的功能,這樣寫起來雖然簡(jiǎn)單,但是整個(gè)繼承體系的可復(fù)用性會(huì)比較差,特別是運(yùn)用多態(tài)比較頻繁時(shí),程序運(yùn)行出錯(cuò)的概率會(huì)非常大。
如果程序違背了里氏替換原則,則繼承類的對(duì)象在基類出現(xiàn)的地方會(huì)出現(xiàn)運(yùn)行錯(cuò)誤。這時(shí)其修正方法是:取消原來的繼承關(guān)系,重新設(shè)計(jì)它們之間的關(guān)系。
關(guān)于里氏替換原則的例子,最有名的是“正方形不是長方形”。當(dāng)然,生活中也有很多類似的例子,例如,企鵝、鴕鳥和幾維鳥從生物學(xué)的角度來劃分,它們屬于鳥類;但從類的繼承關(guān)系來看,由于它們不能繼承“鳥”會(huì)飛的功能,所以它們不能定義成“鳥”的子類。同樣,由于“氣球魚”不會(huì)游泳,所以不能定義成“魚”的子類;“玩具炮”炸不了敵人,所以不能定義成“炮”的子類等。
下面以“幾維鳥不是鳥”為例來說明里氏替換原則。
【例2】里氏替換原則在“幾維鳥不是鳥”實(shí)例中的應(yīng)用。
分析:鳥一般都會(huì)飛行,如燕子的飛行速度大概是每小時(shí) 120 千米。但是新西蘭的幾維鳥由于翅膀退化無法飛行。假如要設(shè)計(jì)一個(gè)實(shí)例,計(jì)算這兩種鳥飛行 300 千米要花費(fèi)的時(shí)間。顯然,拿燕子來測(cè)試這段代碼,結(jié)果正確,能計(jì)算出所需要的時(shí)間;但拿幾維鳥來測(cè)試,結(jié)果會(huì)發(fā)生“除零異?!被蚴恰盁o窮大”,明顯不符合預(yù)期,其類圖如圖 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)+"小時(shí)."); System.out.println("幾維鳥將飛行"+bird2.getFlyTime(300)+"小時(shí)。"); } catch(Exception err) { System.out.println("發(fā)生錯(cuò)誤了!"); } } } //鳥類 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; } }
程序的運(yùn)行結(jié)果如下:
如果飛行300公里: 燕子將飛行2.5小時(shí). 幾維鳥將飛行Infinity小時(shí)。
程序運(yùn)行錯(cuò)誤的原因是:幾維鳥類重寫了鳥類的 setSpeed(double speed) 方法,這違背了里氏替換原則。正確的做法是:取消幾維鳥原來的繼承關(guān)系,定義鳥和幾維鳥的更一般的父類,如動(dòng)物類,它們都有奔跑的能力。幾維鳥的飛行速度雖然為 0,但奔跑速度不為 0,可以計(jì)算出其奔跑 300 千米所要花費(fèi)的時(shí)間。
其類圖如圖 2 所示。
上述就是小編為大家分享的什么是里氏替換原則了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。