一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專(zhuān)注于服務(wù)器技術(shù)及軟件下載分享
分類(lèi)導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務(wù)器之家 - 編程語(yǔ)言 - JAVA教程 - 舉例解析Java的設(shè)計(jì)模式編程中里氏替換原則的意義

舉例解析Java的設(shè)計(jì)模式編程中里氏替換原則的意義

2020-03-26 14:09卡奴達(dá)摩 JAVA教程

這篇文章主要介紹了Java的設(shè)計(jì)模式中里氏替換原則的意義,文中舉例來(lái)說(shuō)明里氏替換原則中強(qiáng)調(diào)的繼承特性方面可能帶來(lái)的問(wèn)題,需要的朋友可以參考下

里氏替換原則,OCP作為OO的高層原則,主張使用“抽象(Abstraction)”和“多態(tài)(Polymorphism)”將設(shè)計(jì)中的靜態(tài)結(jié)構(gòu)改為動(dòng)態(tài)結(jié)構(gòu),維持設(shè)計(jì)的封閉性。“抽象”是語(yǔ)言提供的功能。“多態(tài)”由繼承語(yǔ)義實(shí)現(xiàn)。

里氏替換原則包含以下4層含義:

  1. 子類(lèi)可以實(shí)現(xiàn)父類(lèi)的抽象方法,但是不能覆蓋父類(lèi)的非抽象方法。
  2. 子類(lèi)中可以增加自己特有的方法。
  3. 當(dāng)子類(lèi)覆蓋或?qū)崿F(xiàn)父類(lèi)的方法時(shí),方法的前置條件(即方法的形參)要比父類(lèi)方法的輸入?yún)?shù)更寬松。
  4. 當(dāng)子類(lèi)的方法實(shí)現(xiàn)父類(lèi)的抽象方法時(shí),方法的后置條件(即方法的返回值)要比父類(lèi)更嚴(yán)格。

  現(xiàn)在我們可以對(duì)以上四層含義進(jìn)行講解。

  子類(lèi)可以實(shí)現(xiàn)父類(lèi)的抽象方法,但是不能覆蓋父類(lèi)的非抽象方法

  在我們做系統(tǒng)設(shè)計(jì)時(shí),經(jīng)常會(huì)設(shè)計(jì)接口或抽象類(lèi),然后由子類(lèi)來(lái)實(shí)現(xiàn)抽象方法,這里使用的其實(shí)就是里氏替換原則。子類(lèi)可以實(shí)現(xiàn)父類(lèi)的抽象方法很好理解,事實(shí)上,子類(lèi)也必須完全實(shí)現(xiàn)父類(lèi)的抽象方法,哪怕寫(xiě)一個(gè)空方法,否則會(huì)編譯報(bào)錯(cuò)。

  里氏替換原則的關(guān)鍵點(diǎn)在于不能覆蓋父類(lèi)的非抽象方法。父類(lèi)中凡是已經(jīng)實(shí)現(xiàn)好的方法,實(shí)際上是在設(shè)定一系列的規(guī)范和契約,雖然它不強(qiáng)制要求所有的子類(lèi)必須遵從這些規(guī)范,但是如果子類(lèi)對(duì)這些非抽象方法任意修改,就會(huì)對(duì)整個(gè)繼承體系造成破壞。而里氏替換原則就是表達(dá)了這一層含義。

  在面向?qū)ο蟮脑O(shè)計(jì)思想中,繼承這一特性為系統(tǒng)的設(shè)計(jì)帶來(lái)了極大的便利性,但是由之而來(lái)的也潛在著一些風(fēng)險(xiǎn)。下面舉例來(lái)說(shuō)明繼承的風(fēng)險(xiǎn),我們需要完成一個(gè)兩數(shù)相減的功能,由類(lèi)A來(lái)負(fù)責(zé)。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
class A{
  public int func1(int a, int b){
    return a-b;
  }
}
 
public class Client{
  public static void main(String[] args){
    A a = new A();
    System.out.println("100-50="+a.func1(100, 50));
    System.out.println("100-80="+a.func1(100, 80));
  }
}

 運(yùn)行結(jié)果:

?
1
2
100-50=50
100-80=20

        后來(lái),我們需要增加一個(gè)新的功能:完成兩數(shù)相加,然后再與100求和,由類(lèi)B來(lái)負(fù)責(zé)。即類(lèi)B需要完成兩個(gè)功能:
兩數(shù)相減。
兩數(shù)相加,然后再加100。
        由于類(lèi)A已經(jīng)實(shí)現(xiàn)了第一個(gè)功能,所以類(lèi)B繼承類(lèi)A后,只需要再完成第二個(gè)功能就可以了,代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class B extends A{
  public int func1(int a, int b){
    return a+b;
  }
   
  public int func2(int a, int b){
    return func1(a,b)+100;
  }
}
 
public class Client{
  public static void main(String[] args){
    B b = new B();
    System.out.println("100-50="+b.func1(100, 50));
    System.out.println("100-80="+b.func1(100, 80));
    System.out.println("100+20+100="+b.func2(100, 20));
  }
}

類(lèi)B完成后,運(yùn)行結(jié)果:

?
1
2
3
100-50=150
100-80=180
100+20+100=220

        我們發(fā)現(xiàn)原本運(yùn)行正常的相減功能發(fā)生了錯(cuò)誤。原因就是類(lèi)B在給方法起名時(shí)無(wú)意中重寫(xiě)了父類(lèi)的方法,造成所有運(yùn)行相減功能的代碼全部調(diào)用了類(lèi)B重寫(xiě)后的方法,造成原本運(yùn)行正常的功能出現(xiàn)了錯(cuò)誤。在本例中,引用基類(lèi)A完成的功能,換成子類(lèi)B之后,發(fā)生了異常。在實(shí)際編程中,我們常常會(huì)通過(guò)重寫(xiě)父類(lèi)的方法來(lái)完成新的功能,這樣寫(xiě)起來(lái)雖然簡(jiǎn)單,但是整個(gè)繼承體系的可復(fù)用性會(huì)比較差,特別是運(yùn)用多態(tài)比較頻繁時(shí),程序運(yùn)行出錯(cuò)的幾率非常大。如果非要重寫(xiě)父類(lèi)的方法,比較通用的做法是:原來(lái)的父類(lèi)和子類(lèi)都繼承一個(gè)更通俗的基類(lèi),原有的繼承關(guān)系去掉,采用依賴(lài)、聚合,組合等關(guān)系代替。

 

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 99re在线视频免费观看 | 国产精品久久免费观看 | 美女污视频在线观看 | 亚洲午夜久久久 | 俄罗斯男男激情1069gay | 91天堂素人97年清纯嫩模 | 久久综合香蕉久久久久久久 | 久久理论片迅播影院一级 | 成人福利在线播放 | 秋霞黄色网 | 国产一卡二卡3卡4卡更新 | 日日干影院 | 白丝女仆被啪到深夜漫画 | 俄罗斯引擎首页进入 | 大乳一级一区二区三区 | 成人软件18免费 | 成人精品一区二区三区中文字幕 | 四虎影院永久网站 | jk制服白丝超短裙流白浆 | 99热这里只有精品一区二区三区 | 97精品国产高清在线看入口 | 午夜爱| 拿捏小说 | 久久五月综合婷婷中文云霸高清 | 国产亚洲精品美女 | 亚洲天天综合 | 男人的天堂视频 | 男人好大好硬好爽免费视频 | 久久久久久久尹人综合网亚洲 | 我要看逼| 欧美国产精品久久 | 日本亚洲娇小与黑人tube | aa视频免费 | naruto堂同人本子汉化gg | 国产午夜精品久久理论片 | 国内精品91最新在线观看 | 波多野结衣护士 | 欧美成人tv在线观看免费 | 亚洲人影院 | 青青精品视频 | 国产日韩欧美成人 |