新聞中心
里氏置換原則(Liskov Substitution Principle),簡(jiǎn)稱(chēng)LSP

10年積累的成都做網(wǎng)站、成都網(wǎng)站建設(shè)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶(hù)對(duì)網(wǎng)站的新想法和需求。提供各種問(wèn)題對(duì)應(yīng)的解決方案。讓選擇我們的客戶(hù)得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有日喀則免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
定義:
Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.
所有引用基類(lèi)的地方必須能夠透明的使用其子類(lèi)對(duì)象。
也就是說(shuō),只要父類(lèi)出現(xiàn)的地方子類(lèi)就能夠出現(xiàn),而且替換為子類(lèi)不會(huì)產(chǎn)生任何錯(cuò)誤或異常。但是反過(guò)來(lái),子類(lèi)出現(xiàn)的地方,替換為父類(lèi)就可能出現(xiàn)問(wèn)題了。
這個(gè)原則是為良好的繼承定義一個(gè)規(guī)范,簡(jiǎn)單的講,有4層含義:
一、子類(lèi)必須完全實(shí)現(xiàn)父類(lèi)的方法
定義一個(gè)抽象類(lèi)
- public abstract class ViewPoint {
- //去麗江旅游
- public abstract void where();
- }
下面兩個(gè)類(lèi)是實(shí)現(xiàn)這個(gè)抽象類(lèi)
- public class Lijiang extends ViewPoint {
- @Override
- public void where() {
- System.out.println("歡迎來(lái)到麗江...");
- }
- }
- public class Zhangjiajie extends ViewPoint {
- @Override
- public void where() {
- System.out.println("歡迎來(lái)到張家界...");
- }
- }
人物是涂涂,在里面設(shè)置類(lèi)類(lèi)型來(lái)傳遞參數(shù)。此時(shí)涂涂要去的旅游景點(diǎn)還是抽象的
- public class Tutu {
- //定義要旅游的景點(diǎn)
- private ViewPoint viewpoint;
- //涂涂要去的景點(diǎn)
- public void setViewPoint(ViewPoint viewpoint)
- {
- this.viewpoint = viewpoint;
- }
- public void travelTo()
- {
- System.out.println("涂涂要去旅游了");
- viewpoint.where();
- }
- }
場(chǎng)景類(lèi)。設(shè)置具體要去的景點(diǎn)
- public class Sence {
- public static void main(String args[])
- {
- Tutu tutu = new Tutu();
- //設(shè)置要去的旅游景點(diǎn)
- tutu.setViewPoint(new Lijiang());
- tutu.travelTo();
- }
- }
運(yùn)行結(jié)果:
涂涂要去旅游了
歡迎來(lái)到麗江...
二、子類(lèi)可以有自己的特性
也就是說(shuō)在類(lèi)的子類(lèi)上,可以定義其他的方法或?qū)傩?/p>
三、覆蓋或者實(shí)現(xiàn)父類(lèi)的方法時(shí)輸入?yún)?shù)可以被放大
父類(lèi)能夠存在的地方,子類(lèi)就能存在,并且不會(huì)對(duì)運(yùn)行結(jié)果有變動(dòng)。反之則不行。
父類(lèi),say()里面的參數(shù)是HashMap類(lèi)型,是Map類(lèi)型的子類(lèi)型。(因?yàn)樽宇?lèi)的范圍應(yīng)該比父類(lèi)大)
- import java.util.Collection;
- import java.util.HashMap;
- public class Father {
- public Collection say(HashMap map)
- {
- System.out.println("父類(lèi)被執(zhí)行...");
- return map.values();
- }
- }
子類(lèi),say()里面的參數(shù)變成了Map類(lèi)型,Map范圍比HashMap類(lèi)型大,符合LSP原則。注意這里的say不是覆寫(xiě)父類(lèi)的say,因?yàn)閰?shù)類(lèi)型不同。而是重載。
- import java.util.Collection;
- import java.util.Map;
- /*
- * 子類(lèi)繼承了父類(lèi)的所有屬性
- */
- public class Son extends Father {
- //方法輸入?yún)?shù)類(lèi)型
- public Collection say(Map map)
- {
- System.out.println("子類(lèi)被執(zhí)行...");
- return map.values();
- }
- }
場(chǎng)景類(lèi)
- import java.util.HashMap;
- public class Home {
- public static void main(String args[])
- {
- invoke();
- }
- public static void invoke()
- {
- //父類(lèi)存在的地方,子類(lèi)就應(yīng)該能夠存在
- //Father f = new Father();
- Son s = new Son();
- HashMap map = new HashMap();
- //f.say(map);
- s.say(map);
- }
- }
無(wú)論是用父類(lèi)還是子類(lèi)調(diào)用say方法,得到的結(jié)果都是
父類(lèi)被執(zhí)行...
但是,如果將上面Father里的say參數(shù)改為Map,子類(lèi)Son里的say參數(shù)改為HashMap,得到的結(jié)果就變成了
f.say(map)結(jié)果:父類(lèi)被執(zhí)行...
s.say(map)結(jié)果: 子類(lèi)被執(zhí)行...
這樣會(huì)造成邏輯混亂。所以子類(lèi)中方法的前置條件必須與父類(lèi)中被覆寫(xiě)的前置條件相同或者更寬。
四、覆寫(xiě)或者實(shí)現(xiàn)父類(lèi)的方法時(shí)輸出結(jié)果可以被縮小
其實(shí)與上面的類(lèi)似,也就是父類(lèi)能出現(xiàn)的地方子類(lèi)就可以出現(xiàn),而且替換為子類(lèi)不會(huì)產(chǎn)生任何錯(cuò)誤或者異常,使用者也無(wú)需知道是父類(lèi)還是子類(lèi)。但是反過(guò)來(lái)就不行了,有子類(lèi)出現(xiàn)的地方,父類(lèi)未必就適應(yīng)。(畢竟子類(lèi)的范圍要>=父類(lèi)的范圍)
當(dāng)前文章:設(shè)計(jì)模式6大原則:里氏置換原則
標(biāo)題來(lái)源:http://m.5511xx.com/article/dhdpcdg.html


咨詢(xún)
建站咨詢(xún)
