1. 程式人生 > >設計模式六大原則:里氏替換原則(五)

設計模式六大原則:里氏替換原則(五)

里氏代換原則是由麻省理工學院(MIT)電腦科學實驗室的Liskov女士,在1987年的OOPSLA大會上發表的一篇文章《Data Abstraction and Hierarchy》裡面提出來的,主要闡述了有關繼承的一些原則,也就是什麼時候應該使用繼承,什麼時候不應該使用繼承,以及其中的蘊涵的原理。2002年,我們前面單一職責原則中提到的軟體工程大師Robert C. Martin,出版了一本《Agile Software Development Principles Patterns and Practices》,在文中他把里氏代換原則最終簡化為一句話:“Subtypes must be substitutable for their base types”。也就是,子類必須能夠替換成它們的基類。
我們把里氏代換原則解釋得更完整一些:在一個軟體系統中,子類應該可以替換任何基類能夠出現的地方,並且經過替換以後,程式碼還能正常工作。

定義一:
如果對每一個型別為 T1的物件 o1,都有型別為 T2 的物件o2,使得以 T1定義的所有程式 P 在所有的物件 o1 都代換成 o2 時,程式 P 的行為沒有發生變化,那麼型別 T2 是型別 T1 的子型別。
定義二:
所有引用基類的地方必須能透明地使用其子類的物件。

//
//  里氏替換原則.cpp
//  c++
//
//  Created by 劉龍玲 on 16/5/12.
//  Copyright © 2016年 liulongling. All rights reserved.
//

#include <iostream>
using namespace
std; //案例:鴕鳥非鳥 class Bird { public: bool fly() { //鳥類可以飛; return true; }; int getVelocity() { return this->velocity; } private: int velocity; }; //鴕鳥 class Ostrich: public Bird { bool fly() { //鴕鳥不可以飛; return false; }; int getVelocity() { return
0; } }; int main() { //計算鳥飛越黃河所需的時間。 Bird* bird = new Ostrich; cout<<"h:"<<3000/bird->getVelocity()<<endl; return 0; }

由於C++標準沒有把除0錯當成標準異常,和原生陣列訪問越界為什麼不是一異常一樣,主要還是為了“效率/效能”。C++之父在談C++語言設計的書(The Design and Evolution of C++)裡談到:

“low-level events, such as arithmetic overflows and divide by zero, are assumed to be handled by a dedicated lower-level mechanism rather than by exceptions. This enables C++ to match the behaviour of other languages when it comes to arithmetic. It also avoids the problems that occur on heavily pipelined architectures where events such as divide by zero are asynchronous.”

簡單翻譯一下: “底層的事件,比如計算上的溢位和除0錯,被認為應用有一個同樣底層的機制去處理它們,而不是異常。這讓C++在涉及到算術領域的效能,可以和其它語言競爭。再者,它也避免了當某些事件,比如除0錯是非同步的情況下(譯者注:比如在別一個執行緒裡發生)所可能造成的‘管道重重’的架構這一問題。”所以我換成用java程式碼實現這個案例

package com.lll.test;
//鳥
public class Bird {
    private int velocity;

    public int getVelocity() {
        return velocity;
    }

    public void setVelocity(int velocity) {
        this.velocity = velocity;
    }
}
package com.lll.test;
//鴕鳥
public class Ostrich extends Bird{

    public int getVelocity() {
        return 0;
    }
}
package com.lll.test;

public class main {

    public static void main(String[] args) {
        Bird bird = new Bird();
        bird.setVelocity(100);
        int h = flyTime(bird);
        System.out.println("飛行時間是:"+h);
    }

    public static int flyTime(Bird bird)
    {
        return 3000/bird.getVelocity();
    }
}

執行結果正確:
飛行時間是:30

package com.lll.test;

public class main {

    public static void main(String[] args) {
        Bird bird = new  Ostrich();
        bird.setVelocity(100);
        int h = flyTime(bird);
        System.out.println("飛行時間是:"+h);
    }

    public static int flyTime(Bird bird)
    {
        return 3000/bird.getVelocity();
    }
}

執行結果異常:
Exception in thread “main” java.lang.ArithmeticException: / by zero
at com.lll.test.main.flyTime(main.java:11)
at com.lll.test.main.main(main.java:7)

我們知道,面向物件的語言的三大特點是繼承,封裝,多型,里氏替換原則是依賴於繼承,多型這兩大特性。里氏替換原則的定義是,所有引用基類的地方必須能透明地使用其子類的物件。通俗來講是隻要父類能出現的地方子類就可以出現,而且替換為子類也不會產生任何錯誤和異常。而我們在使用flyTime方法時 ,當使用者flyTime方法裡的引數Bird被Ostrich替換掉後,結果出現了異常,那麼它明顯違背了里氏替換原則。

相關推薦

設計模式六大原則:里氏替換原則()

里氏代換原則是由麻省理工學院(MIT)電腦科學實驗室的Liskov女士,在1987年的OOPSLA大會上發表的一篇文章《Data Abstraction and Hierarchy》裡面提出來的,主要闡述了有關繼承的一些原則,也就是什麼時候應該使用繼承,什麼

設計模式原則——里氏替換原則

里氏替換原則(Liskov Substitution Principle) 定義1:如果對每一個型別為 T1 的物件 o1,都有型別為 T2 的物件 o2,使得以 T1 定義的所有程式 P 在所有的物件 o1 都代換成 o2 時,程式 P 的行為沒有發生變化,那麼型別 T2

設計模式設計原則-里氏替換原則

父類和子類 面嚮物件語言中的繼承,有以下優點: 程式碼共享,減少建立子類的工作量,只要繼承了父類就擁有父類的方法和屬性 提高程式碼重用性 子類可以完全繼承父類的方法,又可以對父類的方法進行重寫,既可以和父類保持一致,也可以有自身的特點 提高程式碼的擴充套件

設計原則---里氏替換原則

本文參考自設計模式之禪(第二版)第二章 1.1 愛恨糾葛的父子關係        在面向物件的語言中,繼承是必不可少的、非常優秀的語言機制,它有如下優點: 程式碼共享,減少建立類的工作量,每個子類都擁有父類的方法和屬性; 提高程式碼的重用性; 子類可以形似父

面向物件六大原則----里氏替換原則,依賴倒置原則

單一職責原則 英文名稱是Single Responsibility Principle,簡稱SRP 開閉原則英文全稱是Open Close Principle,簡稱OCP 里氏替換原則 英文全稱是Liskov Substitution Principle,簡稱LSP 依賴倒置原則 英文全稱是Depe

面向物件設計原則--里氏替換原則(LSP)和依賴倒置原則(DIP)

面向物件設計原則–里氏替換原則(LSP)和依賴倒置原則(DIP) tags:設計模式 LSP–inheritance should ensure that any property prove

java設計原則--里氏替換原則

JAVA設計原則–里氏替換原則(LSP原則) 為什麼要用里氏替換原則?: 為了優化繼承所帶來的缺點,使得繼承的優點發揮到最大,而同時減少缺點帶來的麻煩。 繼承的優缺點: 優點: 1. 程式碼共享,減少建立類的工作量,每個子類都擁有父類的屬性和方

[面向物件六大原則] 里氏替換原則(LSP)

里氏替換原則 - Liskov Substitution Principle定義一:如果對每一個型別為S的物件O1,都有型別為T的物件O2,使得以T定義的所有程式P在所有的物件O1都替換成O2時,程式P的行為沒有發生變化,那麼型別S是型別T的子型別。定義二:所有引用基類的地方

(轉)設計模式六大原則(2):里氏替換原則

     肯定有不少人跟我剛看到這項原則的時候一樣,對這個原則的名字充滿疑惑。其實原因就是這項原則最早是在1988年,由麻省理工學院的一位姓裡的女士(Barbara Liskov)提出來的。 定義1:如果對每一個型別為 T1的物件 o1,都有型別為 T2 的物件o2,使

Java設計模式——六大原則里氏替換

肯定有不少人跟我剛看到這項原則的時候一樣,對這個原則的名字充滿疑惑。其實原因就是這項原則最早是在1988年,由麻省理工學院的一位姓裡的女士(Barbara Liskov)提出來的。 定義1:如果對每一個型別為 T1的物件 o1,都有型別為 T2 的物件o2,使得以 T1定義

設計模式六大原則(2):里氏替換原則

      肯定有不少人跟我剛看到這項原則的時候一樣,對這個原則的名字充滿疑惑。其實原因就是這項原則最早是在1988年,由麻省理工學院的一位姓裡的女士(Barbara Liskov)提出來的。 定義1:如果對每一個型別為 T1的物件 o1,都有型別為 T2 的物件o2,

設計模式六大原則里氏替換原則

里氏替換原則:   子類應當可以替換父類並出現在父類能夠出現的地方。比如:公司搞年度派對,都有員工都可以抽獎,那麼不管是新員工還是老員工,也不管是總部員工還是外派員工,都應當可以參加抽獎。 案例: 1 internal class Program 2 { 3 private s

設計模式六大原則之裏氏替換原則

number -h ole 擁有 method about rect sse 程序 1 裏氏替換原則定義 Liskov於1987年提出了一個關於繼承的原則“Inheritance should ensure that any property proved about su

設計模式六大原則(2):裏氏替換原則

tr1 裏氏替換原則 style tar 裏氏替換 href target 替換 設計模式 XN潮寺贛3PF鋁73瓷Hhttp://weibo.com/p/1005056364252732 壇2偈6v實8uka誆敲wmhttp://weibo.com/p/10050563

學習設計模式 - 六大基本原則之裏氏替換原則

bili 傳遞 如何使用 兼容 秦小波 ati ace 繼續 pointer   設計模式總共有六大基本原則,統稱為SOLID (穩定)原則,分別是S-單一職責原則(Single Responsibility Principle), O-開閉原則(Open closed P

設計模式之禪(里氏替換原則)2018-10-19

介面與抽象類的區別: 介面卡模式:使用不同介面的類所提供的服務為客戶端提供它所期望的介面。 實現: 有一個 MediaPlayer 介面和一個實現了 MediaPlayer 介面的實體類 AudioPlayer。預設情況下,AudioPl

設計模式學習之設計模式原則(一):單一職責原則里氏替換原則

學習設計模式,以《設計模式之禪》為藍本進行總結與學習,今天先記錄設計模式六大原則的兩個原則:單一職責原則(SRP)和里氏替換原則(LSP)。 單一職責原則 Single Responsibilit

"圍觀"設計模式(2)--里氏替換原則(LSP,Liskov Substitution Principle)

在面向物件的程式設計中,里氏替換原則(Liskov Substitution principle)是對子型別的特別定義。它由芭芭拉·利斯科夫(Barbara Liskov)在1987年在一次會議上名為“資料的抽象與層次”的演說中首先提出。里氏替換原則的內容可以描述為: “派生

六大設計原則里氏替換原則

我們都知道繼承是面嚮物件語言中極其重要的一部分語法,當然他的存在給了我們很大的便利,但是同樣他也有很多的缺陷。 繼承是侵入性的,只要繼承,就必須擁有父類的所有屬性和方法; 降低了程式碼的靈活性。子類必須擁有父類的屬性和方法,上子類多了很多的約束; 增強了耦合

六大設計原則(一)單一職責原則里氏替換原則

一、單一職責原則: 英文名Single Responsibility Principle,應該有且僅有一個原因引起類的變更。 There should never be more than one reason for a class to change。 單一職責原則提出