在面向?qū)ο缶幊讨校琒OLID原則是一套廣泛接受的設(shè)計(jì)準(zhǔn)則,旨在提高軟件的可維護(hù)性、可擴(kuò)展性和可重用性。其中,里氏替換原則(Liskov Substitution Principle, LSP)是SOLID原則中的“L”,由Barbara Liskov在1987年提出。這個(gè)原則強(qiáng)調(diào)了子類(lèi)應(yīng)當(dāng)可以替換其父類(lèi)而不影響程序的正確性,從而保證了代碼的可替換性和繼承關(guān)系的合理性。
LSP的核心思想
里氏替換原則的核心在于確保子類(lèi)可以無(wú)縫地替換其父類(lèi),即在不改變程序可見(jiàn)行為的前提下,程序中的任何基類(lèi)對(duì)象都可以被它的子類(lèi)對(duì)象所替換。這意味著,如果一個(gè)方法接受一個(gè)基類(lèi)類(lèi)型的參數(shù),那么它應(yīng)該能夠接受任何派生自該基類(lèi)的子類(lèi)對(duì)象,而無(wú)需知道這個(gè)對(duì)象是基類(lèi)還是某個(gè)子類(lèi)。
LSP的正式定義
- 如果對(duì)于每個(gè)類(lèi)型為T(mén)1的對(duì)象o1,都存在一個(gè)類(lèi)型為T(mén)2的對(duì)象o2,使得在所有從T1定義的程序中,o1都可被o2替換,而不改變?cè)摮绦虻娜魏慰捎^察屬性,那么類(lèi)型T2是類(lèi)型T1的子類(lèi)型。
這個(gè)定義強(qiáng)調(diào)了子類(lèi)型必須能夠替換其父類(lèi)型,同時(shí)保持程序行為的一致性。
LSP的實(shí)踐指南
確保子類(lèi)方法的行為與父類(lèi)一致:如果子類(lèi)重寫(xiě)了父類(lèi)的方法,那么這個(gè)方法的行為應(yīng)該與父類(lèi)中的行為在邏輯上保持一致,或者更為具體(但不應(yīng)改變?cè)幸鈭D)。
避免拋出新的或更廣泛的異常:子類(lèi)方法不應(yīng)拋出比父類(lèi)方法更多或更廣泛的異常,因?yàn)檫@可能會(huì)破壞調(diào)用者的異常處理邏輯。
前置條件不能更嚴(yán)格:子類(lèi)方法接受的前置條件(即調(diào)用該方法前必須滿足的條件)不應(yīng)比父類(lèi)方法更嚴(yán)格。這意味著,如果父類(lèi)方法可以接受某種輸入,子類(lèi)方法也應(yīng)該能夠接受。
后置條件不能更弱:子類(lèi)方法執(zhí)行后的結(jié)果(后置條件)應(yīng)該至少與父類(lèi)方法一樣嚴(yán)格,或者更強(qiáng)。這保證了子類(lèi)方法不會(huì)降低父類(lèi)方法的保證水平。
不變性(Invariants):子類(lèi)不應(yīng)改變父類(lèi)中定義的不變性。不變性是指對(duì)象在其生命周期內(nèi)必須始終保持為真的屬性。
LSP的違反示例
假設(shè)我們有一個(gè)基類(lèi)Bird
,其中有一個(gè)方法fly()
,表示鳥(niǎo)類(lèi)飛行的能力。現(xiàn)在,我們創(chuàng)建了一個(gè)子類(lèi)Ostrich
(鴕鳥(niǎo)),雖然鴕鳥(niǎo)是鳥(niǎo)類(lèi),但它不能飛行。如果我們?cè)谝粋€(gè)期望任何Bird
都能飛行的上下文中使用Ostrich
,就會(huì)違反里氏替換原則,因?yàn)?code style="-webkit-tap-highlight-color: transparent; margin: 0px 2px; padding: 2px 4px; outline: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important; color: rgb(239, 112, 96); line-height: 1.8em; letter-spacing: 0em; background-attachment: scroll; background-clip: border-box; background-image: none; background-origin: padding-box; background-position: 0% 0%; background-repeat: no-repeat; background-size: auto; width: auto; height: auto; border-style: none; border-width: 3px; border-color: rgb(0, 0, 0) rgba(0, 0, 0, 0.4) rgba(0, 0, 0, 0.4); border-radius: 4px; font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace; word-break: break-all;">Ostrich不能替換Bird
而不改變程序的行為(即不能飛行)。
結(jié)論
里氏替換原則是面向?qū)ο笤O(shè)計(jì)中確保繼承關(guān)系合理性的重要原則。它要求子類(lèi)必須能夠完全替代其父類(lèi),而不會(huì)影響程序的正確性。遵循這一原則,可以幫助開(kāi)發(fā)者設(shè)計(jì)出更加健壯、易于維護(hù)和擴(kuò)展的系統(tǒng)。在實(shí)際開(kāi)發(fā)中,我們應(yīng)時(shí)刻注意子類(lèi)與父類(lèi)之間的行為一致性,確保子類(lèi)能夠無(wú)縫替換父類(lèi),從而避免潛在的錯(cuò)誤和設(shè)計(jì)問(wèn)題。
該文章在 2024/11/15 12:45:41 編輯過(guò)