在面向?qū)ο蟮恼Z(yǔ)言中,繼承是必不可少的、非常優(yōu)秀的語(yǔ)言機(jī)制,它有如下優(yōu)點(diǎn):
- 代碼共享,減少創(chuàng)建類(lèi)的工作量,每個(gè)子類(lèi)都擁有父類(lèi)的方法和屬性。
- 提高代碼的重用性。
- 子類(lèi)可以形似父類(lèi),但又異于父類(lèi)。
- 提高代碼的可擴(kuò)展性。
- 提高產(chǎn)品或項(xiàng)目的開(kāi)放性。
繼承的缺點(diǎn)如下:
- 繼承是侵入性的,只要繼承,就必須擁有父類(lèi)的所有屬性和方法。
- 降低代碼的靈活性。
- 增強(qiáng)了耦合性。當(dāng)父類(lèi)的常量、變量和方法被修改時(shí),需要考慮子類(lèi)的修改,而且在缺乏規(guī)范的環(huán)境下,這種修改可能需要代碼重構(gòu)。
如何讓繼承的利大于弊,解決的方案是引入里氏替換原則。
里氏替換原則(LSP)的定義:
- 嚴(yán)格的定義:如果對(duì)每一個(gè)類(lèi)型為T(mén)1的對(duì)象o1,都有類(lèi)型為T(mén)2的對(duì)象o2,使得以T1定義的所有程序P在所有的對(duì)象o1都換成o2時(shí),程序P的行為沒(méi)有變化,那么類(lèi)型T2是類(lèi)型T1的子類(lèi)型。
- 通俗的定義:所有引用基類(lèi)的地方必須能透明地使用其子類(lèi)的對(duì)象。
- 更通俗的定義:子類(lèi)可以擴(kuò)展父類(lèi)的功能,但不能改變父類(lèi)原有的功能。
里氏替換原則包含以下4層含義:
- 子類(lèi)可以實(shí)現(xiàn)父類(lèi)的抽象方法,但是不能覆蓋父類(lèi)的非抽象方法。
- 子類(lèi)中可以增加自己特有的方法。
- 當(dāng)子類(lèi)覆蓋或?qū)崿F(xiàn)父類(lèi)的方法時(shí),方法的前置條件(即方法的形參)要比父類(lèi)方法的輸入?yún)?shù)更寬松。
- 當(dāng)子類(lèi)的方法實(shí)現(xiàn)父類(lèi)的抽象方法時(shí),方法的后置條件(即方法的返回值)要比父類(lèi)更嚴(yán)格。