日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java solid设计原则_六大设计原则之里氏替换原则(LSP)

發布時間:2024/3/7 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java solid设计原则_六大设计原则之里氏替换原则(LSP) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、SOLID

設計模式的六大原則有:

Single Responsibility Principle:單一職責原則

Open Closed Principle:開閉原則

Liskov Substitution Principle:里氏替換原則

Law of Demeter:迪米特法則

Interface Segregation Principle:接口隔離原則

Dependence Inversion Principle:依賴倒置原則

把這六個原則的首字母聯合起來(兩個 L 算做一個)就是 SOLID (solid,穩定的),其代表的含義就是這六個原則結合使用的好處:建立穩定、靈活、健壯的設計。下面我們來看一下里氏替換原則。

設計模式六大原則(SOLID)

二、里氏替換原則定義

【所有引用基類的地方必須能透明地使用其子類的對象】

Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.

三、里氏替換原則彌補繼承的缺陷

氏替換原則的意思是,所有基類在的地方,都可以換成子類,程序還可以正常運行。這個原則是與面向對象語言的繼承特性密切相關的。

在學習java類的繼承時,我們知道繼承有一些優點:

子類擁有父類的所有方法和屬性,從而可以減少創建類的工作量。

提高了代碼的重用性。

提高了代碼的擴展性,子類不但擁有了父類的所有功能,還可以添加自己的功能。

但有優點也同樣存在缺點:

繼承是侵入性的。只要繼承,就必須擁有父類的所有屬性和方法。

降低了代碼的靈活性。因為繼承時,父類會對子類有一種約束。

增強了耦合性。當需要對父類的代碼進行修改時,必須考慮到對子類產生的影響。

如何揚長避短呢?方法是引入里氏替換原則。

四、里氏替換原則對繼承進行了規則上的約束

里氏替換原則對繼承進行了規則上的約束,這種約束主要體現在四個方面:

子類必須實現父類的抽象方法,但不得重寫(覆蓋)父類的非抽象(已實現)方法。

子類中可以增加自己特有的方法。

當子類覆蓋或實現父類的方法時,方法的前置條件(即方法的形參)要比- 父類方法的輸入參數更寬松。(即只能重載不能重寫)

當子類的方法實現父類的抽象方法時,方法的后置條件(即方法的返回值)要比父類更嚴格。

下面對以上四個含義進行詳細的闡述

4.1、子類必須實現父類的抽象方法,但不得重寫(覆蓋)父類的非抽象(已實現)方法

在我們做系統設計時,經常會設計接口或抽象類,然后由子類來實現抽象方法,這里使用的其實就是里氏替換原則。若子類不完全對父類的方法進行實例化,那么子類就不能被實例化,那么這個接口或抽象類就毫無存在的意義了。

里氏替換原則規定,子類不能覆寫父類已實現的方法。父類中已實現的方法其實是一種已定好的規范和契約,如果我們隨意的修改了它,那么可能會帶來意想不到的錯誤。下面舉例說明一下子類覆寫了父類方法帶來的后果。

public classFather {public void fun(int a, intb) {

System.out.println(a+ "+" + b + "=" + (a +b));

}

}public class Sun extendsFather {

@Overridepublic void fun(int a, intb) {

System.out.println(a+ "-" + b + "=" + (a -b));

}

}public classClient {public static voidmain(String[] args) {

Father father= newFather();

father.fun(1, 2);//父類存在的地方,可以用子類替代//子類Sun替代父類Father

System.out.println("子類替代父類后的運行結果");

Sun sun= newSun();

sun.fun(1, 2);

}

}

運行結果:

1+2=3子類替代父類后的運行結果1-2=-1

我們想要的結果是“1+2=3”。可以看到,方法重寫后結果就不是了我們想要的結果了,也就是這個程序中子類B不能替代父類A。這違反了里氏替換原則,從而給程序造成了錯誤。

我們可以給父類的非抽象(已實現)方法加final修飾,這樣就在語法層面控制了父類非抽象方法被子類重寫而違反里氏替換原則。

有時候父類有多個子類(Sun1、Sun2),但在這些子類中有一個特例(Sun2)。要想滿足里氏替換原則,又想滿足這個子類的功能時,有的伙伴可能會修改父類(Father)的方法。但是,修改了父類的方法又會對其他的子類造成影響,產生更多的錯誤。這是怎么辦呢?我們可以為這個特例(Sun2)創建一個新的父類(Father2),這個新的父類擁有原父類的部分功能(Father2并不繼承Father,而是持有Father的一個引用,組合Father,調用Father里的功能),又有不同的功能。這樣既滿足了里氏替換原則,又滿足了這個特例的需求。

4.2、子類中可以增加自己特有的方法

這個很容易理解,子類繼承了父類,擁有了父類和方法,同時還可以定義自己有,而父類沒有的方法。這是在繼承父類方法的基礎上進行功能的擴展,符合里氏替換原則。

4.3 、當子類覆蓋或實現父類的方法時,方法的前置條件(即方法的形參)要比父類方法的輸入參數更寬松

先看一段代碼:

public classFather {public voidfun(HashMap map){

System.out.println("父類被執行...");

}

}public class Sun extendsFather {public voidfun(Map map){

System.out.println("子類被執行...");

}

}public classClient {public static voidmain(String[] args) {

System.out.print("父類的運行結果:");

Father father=newFather();

HashMap map=newHashMap();

father.fun(map);//父類存在的地方,可以用子類替代//子類B替代父類A

System.out.print("子類替代父類后的運行結果:");

Sun sun=newSun();

sun.fun(map);

}

}

運行結果:

父類的運行結果:父類被執行...

子類替代父類后的運行結果:父類被執行...

我們應當主意,子類并非重寫了父類的方法,而是重載了父類的方法。因為子類和父類的方法的輸入參數是不同的。子類方法的參數Map比父類方法的參數HashMap的范圍要大,所以當參數輸入為HashMap類型時,只會執行父類的方法,不會執行子類的重載方法。這符合里氏替換原則。

但如果我將子類方法的參數范圍縮小會怎樣?看代碼:

public classFather {public voidfun(Map map){

System.out.println("父類被執行...");

}

}public class Sun extendsFather {public voidfun(HashMap map){

System.out.println("子類被執行...");

}

}public classClient {public static voidmain(String[] args) {

System.out.print("父類的運行結果:");

Father father=newFather();

HashMap map=newHashMap();

father.fun(map);//父類存在的地方,可以用子類替代//子類B替代父類A

System.out.print("子類替代父類后的運行結果:");

Sun sun=newSun();

sun.fun(map);

}

}

運行結果:

父類的運行結果:父類被執行...

子類替代父類后的運行結果:子類被執行...

在父類方法沒有被重寫的情況下,子方法被執行了,這樣就引起了程序邏輯的混亂。所以子類中方法的前置條件必須與父類中被覆寫的方法的前置條件相同或者更寬松。

4.4、當子類的方法實現父類的(抽象)方法時,方法的后置條件(即方法的返回值)要比父類更嚴格

public abstract classFather {public abstractMap fun();

}public class Sun extendsFather {

@OverridepublicHashMap fun() {

System.out.println("子類被執行...");return null;

}

}public classClient {public static voidmain(String[] args) {

Father father=newSun();

father.fun();

}

}

運行結果:

子類被執行...

注意:是實現父類的抽象方法,而不是父類的非抽象(已實現)方法,不然就違法了第一條。

若在繼承時,子類的方法返回值類型范圍比父類的方法返回值類型范圍大,在子類重寫該方法時編譯器會報錯。(Java語法)

總結

以上是生活随笔為你收集整理的java solid设计原则_六大设计原则之里氏替换原则(LSP)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日本一区二区在线视频 | 嫩草影院懂你的影院 | 免费无码国产精品 | 亚洲二区在线播放视频 | 韩国av一区二区三区 | 免费看的黄色录像 | 夫妻露脸自拍[30p] | 9l视频自拍蝌蚪9l视频成人 | 欧美经典一区二区三区 | 大桥未久视频在线观看 | 国产av国片偷人妻麻豆 | 91视频社区| 妇女一级片 | 麻豆午夜 | 伊人色播 | 一本到免费视频 | 国产精品自拍在线观看 | 日韩av电影手机在线观看 | 午夜噜噜| 免费播放毛片 | 亚洲精品中文字幕在线观看 | 精品国产av一区二区 | 在线免费看黄色 | 人人做人人爱人人爽 | 欧美黄色小说视频 | 日韩精品一区二区在线 | 69精品国产 | 亚洲自拍av在线 | 国产在线观看第一页 | 亚洲欧洲综合av | 精品成人一区二区三区 | 成人在线免费看视频 | 动漫3d精品一区二区三区乱码 | 中文字幕一区二区三区免费视频 | 亚洲无套 | 欧美日韩中文字幕 | 欧美性爱视频久久 | 欧美日韩一卡二卡三卡 | 夜夜久久久 | 妻色成人网 | 国产精品一区久久 | 日本久久精品 | 婷婷丁香一区二区三区 | a三级黄色片 | 特级西西444www大精品视频免费看 | 加勒比av在线播放 | 又大又硬又爽免费视频 | 97av免费视频 | 日本熟妇色xxxxx日本免费看 | 欧美色拍| 国产21页| 国产日韩欧美中文字幕 | 欧美黑人精品一区二区 | 免费a视频在线观看 | 国产情侣自拍小视频 | 女同在线观看 | 国产成人无码AA精品区 | 嫩草国产精品 | 三级黄色片免费观看 | 久久精品在这里 | 欧美人与野 | 国产欧美久久一区二区三区 | 无套内谢88av免费看 | 超碰99在线 | 国产男男gay | 日日操日日干 | 一区三区在线 | 久久这里精品 | 成年视频在线 | 欧美激情在线一区二区 | 午夜精品久久久内射近拍高清 | 伊人情人综合网 | 艳妇乳肉豪妇荡乳xxx | 爱射综合| 国产精品羞羞答答在线 | 天天爽夜夜操 | 成人综合影院 | 青青草成人网 | ww黄色 | 免费观看成人毛片 | 成人污污视频在线观看 | 久久视频热 | 久久国产亚洲精品无码 | 男男gay同性三级 | 草草影院在线观看视频 | 亚洲v国产v欧美v久久久久久 | 无码人妻一区二区三区一 | 手机看片福利永久 | 欧美色啪| 亚洲专区欧美专区 | 中文字幕一区二区三区四区五区 | 黄色性大片 | 99re在线国产 | 亚洲av无码久久精品狠狠爱浪潮 | 久久久久五月 | 折磨小男生性器羞耻的故事 | 欧美视频一区二区 | 国产91精品久久久久 | 午夜av一区二区三区 |