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