芮氏置換原則(Liskov Substitution Principle),簡稱LSP
定義:
Functions that use pointers or references to base classes must be able to use objects of derived classit .
所有引用基底類別的地方必須能夠透明的使用其子類別物件。
也就是說,只要父類別出現的地方子類別就能夠出現,而且替換為子類別不會產生任何錯誤或異常。但是反過來,子類別出現的地方,替換為父類別就可能出現問題了。
這個原則是為良好的繼承定義一個規範,簡單的講,有4層意義:
一、子類別必須完全實作父類別的方法
定義一個抽象類別
public abstract class ViewPoint { //去丽江旅游 public abstract void where(); }
下面兩個類別是實作這個抽象類別
public class Lijiang extends ViewPoint { @Override public void where() { System.out.println("欢迎来到丽江..."); } } public class Zhangjiajie extends ViewPoint { @Override public void where() { System.out.println("欢迎来到张家界..."); } }
角色是塗塗,在裡面設定類別類型來傳遞參數。此時塗塗要去的旅遊景點還是抽象的
public class Tutu { //定义要旅游的景点 private ViewPoint viewpoint; //涂涂要去的景点 public void setViewPoint(ViewPoint viewpoint) { this.viewpoint = viewpoint; } public void travelTo() { System.out.println("涂涂要去旅游了"); viewpoint.where(); } }
場景類別。設定具體要去的景點
public class Sence { public static void main(String args[]) { Tutu tutu = new Tutu(); //设置要去的旅游景点 tutu.setViewPoint(new Lijiang()); tutu.travelTo(); } }
運行結果:
塗塗要去旅遊了
歡迎來到麗江...
二、子類別可以有自己的特性
也就是說在類別的子類別上,可以定義其他的方法或屬性
三、覆寫或實作父類別的方法時輸入參數可以被放大
父類別能夠存在的地方,子類別就能存在,並且不會對運行結果有變動。反之則不行。
父類,say()裡面的參數是HashMap類型,是Map類型的子類型。 (因為子類別的範圍應該比父類大)
import java.util.Collection; import java.util.HashMap; public class Father { public Collection say(HashMap map) { System.out.println("父类被执行..."); return map.values(); } }
子類,say()裡面的參數變成了Map類型,Map範圍比HashMap類型大,符合LSP原則。注意這裡的say不是要覆寫父類別的say,因為參數型別不同。而是重載。
import java.util.Collection; import java.util.Map; /* * 子类继承了父类的所有属性 */ public class Son extends Father { //方法输入参数类型 public Collection say(Map map) { System.out.println("子类被执行..."); return map.values(); } }
場景類別
import java.util.HashMap; public class Home { public static void main(String args[]) { invoke(); } public static void invoke() { //父类存在的地方,子类就应该能够存在 //Father f = new Father(); Son s = new Son(); HashMap map = new HashMap(); //f.say(map); s.say(map); } }
無論是用父類別或子類別呼叫say方法,得到的結果都是
父類別被執行...
但是,如果將上面Father裡的say參數改為Map,子類別Son裡的say參數改為HashMap,得到的結果就變成了
f.say(map)結果:父類被執行...
s.say(map)結果:子類別被執行...
這樣會造成邏輯混亂。所以子類別中方法的前置條件必須與父類別中被覆寫的前置條件相同或更寬。
四、覆寫或實作父類別的方法時輸出結果可以被縮小
其實與上面的類似,也就是父類別能出現的地方子類就可以出現,而且替換為子類別不會產生任何錯誤或異常,使用者也不需要知道是父類別還是子類別。但反過來就不行了,有子類別出現的地方,父類未必就適應。 (畢竟子類別的範圍要>=父類別的範圍)
以上是Java設計模式的里氏置換原則是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!