設(shè)計(jì)模式系列(四)七大設(shè)計(jì)原則-----里氏替換原則

里氏替換原則

  1. java OO 中繼承性的思考和說(shuō)明:
  • 繼承包含這樣一層含義:父類中凡是已經(jīng)實(shí)現(xiàn)好的方法务热,實(shí)際上就是在設(shè)定規(guī)范和契約鞠鲜,雖然它不強(qiáng)制要求所有的子類必須遵循這些契約冲粤,但是如果子類對(duì)這些已經(jīng)實(shí)現(xiàn)的方法任意修改祝闻,就會(huì)對(duì)這個(gè)繼承體系造成破壞。
  • 繼承在給程序設(shè)計(jì)帶來(lái)便利的同時(shí)是牢,也帶來(lái)了弊端碉克。比如使用繼承會(huì)給程序帶來(lái) 傾入性凌唬,程序的可移植性就會(huì)降低,會(huì)增加對(duì)象間的耦合性漏麦,如果一個(gè)類被其他的類所繼承,則當(dāng)這個(gè)類需要修改的時(shí)候况褪,即 當(dāng)父類需要修改的時(shí)候撕贞,必須要考慮到子類,因?yàn)榭赡芨割愋薷暮蟛舛猓欣^承的子類的功能方法都有可能產(chǎn)生問(wèn)題故障
  • 在實(shí)際編程中捏膨,如何正常的使用繼承----- 里氏替換原則
  1. 里氏替換原則介紹:
  • 如果對(duì)每個(gè)類型為 T1 的對(duì)象 O1,都有類型為 T2 的對(duì)象 O2,使得以 T1 定義的所有程序 P 在所有的對(duì)象 O1 都待換成 O2 時(shí)号涯,程序 P 的行為沒(méi)有發(fā)送變化目胡,那么類型 T2 是類型 T1 的子類型。換句話說(shuō)链快,所有引用基類的地方必須能透明的使用其子類的對(duì)象誉己。
  • 在使用繼承的時(shí)候,遵循里氏替換原則域蜗,在 子類中盡量不要重寫(xiě)父類的方法
  • 里氏替換原則告訴我們巨双,繼承實(shí)際上讓兩個(gè)類 耦合性 增強(qiáng)了 (通俗的說(shuō),子類繼承了父類霉祸,父類一旦變化了筑累,子類就必須要跟著變了,所以說(shuō)耦合性增強(qiáng)了)丝蹭,在適當(dāng)?shù)那闆r下慢宗,可以通過(guò) 聚合,組合奔穿,依賴 來(lái)解決問(wèn)題镜沽。

案例

  1. 代碼案例
public class Liskov {
    public static void main(String[] args) {
        A a = new A();
        System.out.println("11-3=" + a.func1(11, 3));
        System.out.println("1-8=" + a.func1(1, 8));
        System.out.println("-----------------------");
        
        B b = new B();
        System.out.println("11-3=" + b.func1(11, 3));//這里本意是求出11-3
        System.out.println("1-8=" + b.func1(1, 8));// 1-8
        System.out.println("11+3+9=" + b.func2(11, 3));
    }
}

// A 類
class A {
// 返回兩個(gè)數(shù)的差
    public int func1(int num1, int num2) {
        return num1 - num2;
    }
}

// B 類繼承了A
// 增加了一個(gè)新功能:完成兩個(gè)數(shù)相加,然后和9 求和
class B extends A {
    //這里淘邻,重寫(xiě)了A 類的方法, 可能是無(wú)意識(shí)
    public int func1(int a, int b) {
        return a + b;
    }
    public int func2(int a, int b) {
        return func1(a, b) + 9;
    }
}
  1. 解決方法
  • 我們發(fā)現(xiàn)原來(lái)正常的減法功能發(fā)生了錯(cuò)誤宾舅。原因就是類 B 無(wú)意中重寫(xiě)了父類的方法,造成原有功能出現(xiàn)錯(cuò)誤蔬蕊。在實(shí)際編程中,我們常常會(huì)通過(guò)重寫(xiě)父類的方法完成新的功能猜扮,這樣寫(xiě)起來(lái)雖然簡(jiǎn)單旅赢,但整個(gè)繼承體系的復(fù)用性會(huì)比較差煮盼。特別是運(yùn)行多態(tài)比較繁瑣的時(shí)候
  • 通用的方法就是: 原有的父類和子類都繼承一個(gè)更加通俗的 BaseClass 基礎(chǔ)類香到,并且將原本的父類與子類之間的繼承關(guān)系去掉养渴,采用 依賴,聚合藐唠,組合 等關(guān)系替代
  • 改進(jìn)方案:


    父類與子類繼承更加基礎(chǔ)的Base類

改進(jìn)

  1. 代碼
public class Liskov {
    public static void main(String[] args) {
        A a = new A();
        System.out.println("11-3=" + a.func1(11, 3));
        System.out.println("1-8=" + a.func1(1, 8));
        System.out.println("-----------------------");
        
        B b = new B();
        //因?yàn)锽 類不再繼承A 類自赔,因此調(diào)用者润脸,不會(huì)再func1 是求減法
        //調(diào)用完成的功能就會(huì)很明確
        System.out.println("11+3=" + b.func1(11, 3));//這里本意是求出11+3
        System.out.println("1+8=" + b.func1(1, 8));// 1+8
        System.out.println("11+3+9=" + b.func2(11, 3));
        //使用組合仍然可以使用到A 類相關(guān)方法
        System.out.println("11-3=" + b.func3(11, 3));// 這里本意是求出11-3
    }
}

//創(chuàng)建一個(gè)更加基礎(chǔ)的基類
class Base {
//把更加基礎(chǔ)的方法和成員寫(xiě)到Base 類
}

// A 類繼承 Base 基礎(chǔ)類
class A extends Base {
    // 返回兩個(gè)數(shù)的差
    public int func1(int num1, int num2) {
        return num1 - num2;
    }
}

// B 類繼承 Base 基礎(chǔ)類
class B extends Base {
    //如果B 需要使用A 類的方法,使用組合關(guān)系
    private A a = new A();
    
    //這里灾测,重寫(xiě)了A 類的方法, 可能是無(wú)意識(shí)
    public int func1(int a, int b) {
        return a + b;
    }
    public int func2(int a, int b) {
        return func1(a, b) + 9;
    }
    
    //我們?nèi)匀幌胧褂肁 的方法
    public int func3(int a, int b) {
        return this.a.func1(a, b);
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市稠项,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌精刷,老刑警劉巖埂软,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丽惶,死亡現(xiàn)場(chǎng)離奇詭異钾唬,居然都是意外死亡奕巍,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)睹酌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)旺芽,“玉大人,你說(shuō)我怎么就攤上這事〉衷酰” “怎么了尝艘?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)姿染。 經(jīng)常有香客問(wèn)我背亥,道長(zhǎng),這世上最難降的妖魔是什么悬赏? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任狡汉,我火速辦了婚禮,結(jié)果婚禮上闽颇,老公的妹妹穿的比我還像新娘盾戴。我一直安慰自己,他們只是感情好进萄,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布捻脖。 她就那樣靜靜地躺著,像睡著了一般中鼠。 火紅的嫁衣襯著肌膚如雪可婶。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,268評(píng)論 1 309
  • 那天援雇,我揣著相機(jī)與錄音矛渴,去河邊找鬼。 笑死惫搏,一個(gè)胖子當(dāng)著我的面吹牛具温,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播筐赔,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼铣猩,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了茴丰?” 一聲冷哼從身側(cè)響起达皿,我...
    開(kāi)封第一講書(shū)人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎贿肩,沒(méi)想到半個(gè)月后峦椰,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡汰规,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年汤功,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片溜哮。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡滔金,死狀恐怖色解,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鹦蠕,我是刑警寧澤冒签,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站钟病,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏刚梭。R本人自食惡果不足惜肠阱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望朴读。 院中可真熱鬧屹徘,春花似錦、人聲如沸衅金。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)氮唯。三九已至鉴吹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惩琉,已是汗流浹背豆励。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瞒渠,地道東北人良蒸。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像伍玖,于是被迫代替她去往敵國(guó)和親嫩痰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359