1.基本介紹
里斯科瓦(Barbara Liskov)使美國麻省理工學院電氣工程于計算機科學系資深教授,她是美國國家工程院院士,在程式語言、分布式計算、程式設計方法及軟體工程領域做出了卓越貢獻,里斯科瓦于1987年提出了一個關于繼承的原則,也就是現在我們稱為的“里氏替換原則”,
里氏替換原則基于子類物件可以賦給父類物件的“多型性”,表明子類可以替換父類,并且出現在父類能夠出現的任何地方,但是該原則要求繼承時需要遵守以下兩點:
- 繼承必須確保父類所擁有的“性質”在子類中仍然成立,且子類的程式執行無例外,
- 子類可以新增特有方法,并且可以重寫父類的抽象方法,但不能改變父類原有的方法,
這兩點也主要是衡量繼承的使用是否符合了里氏替換原則的標準,
2.繼承的濫用
通過一段小故事來講解,為了讓程式達到復用效果,濫用繼承且不遵守“里氏替換原則”從而使程式帶來意想不到的麻煩,
張三在學習了面向物件的技術后,深刻的感受到繼承復用帶來的快感,于是使用面向物件技術開發了一款“模擬鴨子游戲”,游戲中會出現各種鴨子,我們可以操作不同的鴨子進行游泳戲水或是呱呱叫,因為它采用了繼承的特性,設計了一個鴨子父類,并讓不同種類的鴨子都繼承此父類,
隨著游戲市場的競爭壓力加劇,張三為了讓自己的“模擬鴨子游戲”在市場上更受歡迎,張三開發擴展了一個新的功能,就是讓游戲中所有鴨子可以飛行,此時的張三已經被繼承的魅力沖昏了頭腦,他想到鴨子都有翅膀,只需要在Duck類中加上Fly()方法,基于繼承的特性所有鴨子都會復用這個Fly()方法,他心里想:“妙啊,這可真是一招定乾坤啊”,
“模擬鴨子游戲”在加入飛行功能投入市場后,可怕的問題發生了,某個玩家將一只“橡皮鴨”既然操作飛了起來,這顯然不符合一個程式的正常邏輯,因此張三受到了公司的嚴厲制裁,不僅游戲被下架還被罰款,這是怎么回事?張三為了讓程式整體達到復用效果,忽略了極個別的鴨子其實并不具備飛行的能力,這使得某些并不適用該行為(飛行)的子類,也具有了該行為,
這個故事告訴了我們,為了讓程式達到復用的效果,繼承并不是一個“以逸待勞”的方案,使用繼承來達到復用必須要求繼承的成員在所有子類中均有統一性,張三之所以沒有使用好繼承,就是因為他使用的繼承過于片面,且沒有遵守里氏替換原則,然而,理解里氏替換原則的最終目的,就是促使我們更好的、規范的使用繼承,能夠明白什么時候什么情況下正確的使用繼承,以及其中蘊含的原理,
3.讓繼承性質合理化
接著張三開發“模擬鴨子游戲”的故事例子,我們來針對其中出現的問題:“即在使用繼承程序中,為父類加入新的行為,從而導致某些并不適合該行為的子類,也被迫繼承該行為,”來通過UML圖的方式,介紹兩種如何解決問題的方式,當然方式不止兩種,但我們最終目的是要讓我們的繼承符合“里氏替換原則”,
1.切斷不合理繼承,擴展新的父類,
設計思路:從Duck類中去除了Fly方法,以此切斷了橡皮鴨繼承Fly方法的途徑,然后新增“動物鴨”類包含Fly的方法,將會飛的鴨子繼承之該類,并且可以間接繼承Duck類中的共有特性(叫、游泳),
2.組合方式
設計思路:該方式的做法和“繼承”不同的地方在于,“Fly方法”不是繼承來的,而是通過一個介面“組合”來的,子類可以根據自身情況實體化不同的“飛行介面實作類”來執行相應的飛行功能,該方式相對于第一種較為復雜,因為基本上已經形成了一個設計模式“策略模式”,在該章節對該模式不進行詳細介紹,目前只用知道有這種方式即可,后續在對于的專題會詳細展開,
知識改變命運轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/469859.html
標籤:其他