---里斯替換原則(LSP)

什麼里斯替換原則

定義1:如果對每一個類型爲S的對象o1,都有類型T的對象o2,在程序P中,使得T定義的o1都能替代成o2,而程序P的行爲沒有發生變化,那麼類型S是類型T的子類型。
定義2:所有應用基類的地方必須能夠透明地使用其子類的對象。

2個定義都是可以的,只是第2種讀起來比較繞口,第2個比較簡潔,個人建議多品一品定義1。

里斯替換規則

  1. 其他類應該依賴父類或接口
//學生
class Student{
    public String name;
}

//老師
class Teacher{
    //報名
    public static void signUp(Student student){
         System.out.println("當前報名學生姓名:"+student.name);
    }
}

//學生張三
class ZhangSan extends Student{
}

class TeacherWang{
  //報名
    public static void signUp(ZhangSan zhangSan){
         System.out.println("當前報名學生姓名:"+zhangSan.name);
    }
}

看看上面的區別,Teacher依賴的是Student,而TeacherWang依賴的是的ZhangSan,可以說TeacherWang是不符合LSP原則,當然我們在設計程序的時候,並不是全部都要使用這個原則,有的時候也是直接依賴子類的,這個要看具體的需求。
2. 子類必須完全是父類的方法

Class Student{
    //獲取學生證
    public abstract String getStudentID();
}

Class ZhangSan extends Student{
     public String getStudentID(){
        return null;
    }
}

我們看ZhangSan是Student的子類,但是沒有實現getStudentID()方法,假如學校門衛是根據學生證,讓你走進校園,如果沒有學生證,那就沒有資格進入校園,那就相當於不是學生。

  1. 子類可以有不同於父類的方法和屬性
    ZhangSan、LiSi都是Student,那麼他們就有所有Student的屬性和方法,但是ZhangSan喜歡下象棋,LiSi喜歡打籃球,那麼這樣也是可以的,那麼反過來講就不成立了,難道只要是Student都喜歡打籃球和下象棋嗎?

  2. 重載父類的方法,參數類型>=重載參數 或 參數類型 != 重載參數

//父類
class Parent {
    public void test(HashMap hashMap){}
}

//子類
class Child extends Parent{
    @Override
    public void test(HashMap hashMap){}

    public void test(Map map){}

    public void test(String text){}
}

//程序P
class Test{
    public static void main(String[] args){
        //使用父類
        Parent parent = new Parent();
        HashMap hashMap = new HashMap();
        parent.test(hashMap);

     //用子類進行替換
     //Child child = new Child ();
     //HashMap hashMap = new HashMap();
     //child.test(hashMap);
   }
}

//根據定義1,咱們把Parent換成Child,最終調用的還是Parent裏面的方法。

反之看看成立嗎?

//父類
class Parent {

    public void test(Map map){}
}

//子類
class Child extends Parent{

    public void test(HashMap hashMap){}
    @Override
    public void test(Map map){}

    public void test(String text){}
}

//程序P
class Test{
    public static void main(String[] args){
        //使用父類
        Parent parent = new Parent();
        HashMap hashMap = new HashMap();
        parent.test(hashMap);

     //用子類進行替換
     //Child child = new Child ();
     //HashMap hashMap = new HashMap();
     //child.test(hashMap);
   }
}

替換之後發現child調用的不是父類的test(Map map)方法,而是自己的test(HashMap hashMap)方法,不符合定義1,替換之後不印象程序P的功能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章