1. 程式人生 > >關於里氏替換原則與多型概念糾正

關於里氏替換原則與多型概念糾正

public abstract class Quadrangle{
protected abstract void getWidth();
protected abstract void getHeight();
}
public class Rectangle extends Quadrangle {
    private long width;
    private long height;

    public void setWidth(long width) {
        this.width = width;
    }

    public long getWidth() {
        return this.width;
    }

    public void setHeight(long height) {
        this.height = height;
    }

    public long getHeight() {
        return this.height;
    }
}
package com.designphilsophy.lsp.version2;

/**
 * 自己宣告height和width
 * @author xingjiarong
 *
 */
public class Square extends Quadrangle 
{
    private long width;
    private long height;

    public void setWidth(long width) {
        this.height = width;
        this.width = width;
    }

    public long getWidth() {
        return width;
    }

    public void setHeight(long height) {
        this.height = height;
        this.width = height;
    }

    public long getHeight() {
        return height;
    }
}

想必談到設計模式,不可避免要扯一扯的便是這著名的六大原則。

其中最為重要也常有初學者心懷疑慮的就是今天要說得里氏替換原則。

首先,先說說這究竟是個什麼概念。

里氏,是一個姓裡的外國人,這原則就是他提出的。

里氏替換原則(LSP)的定義:所有父類存在的地方都能透明的使用其子類的物件。里氏替換原則告訴我們,在軟體中將一個基類物件替換成它的子類物件,程式不會產生任何錯誤,如果一個軟體實體使用的是一個子類物件的話,那麼它不一定能夠使用基類物件。里氏替換原則是實現開閉原則的重要方式之一,由於使用基類物件的地方都可以使用子類物件,因此在程式中儘量使用基類型別來對物件進行定義,而在執行時再確定其子類型別,用子類物件來替換父類物件。


##里氏替換原則為良好的繼承定義了一個規範,它包含了4層定義:


子類必須完全實現父類的方法。
子類可以有自己的個性。
覆蓋或實現父類的方法時輸入引數可以被放大。
覆寫或實現父類的方法時輸出結果可以被縮小。
採用里氏替換原則的目的就是增強程式的健壯性,版本升級時也可以保持非常好的相容性。即使增加子類,原有的子類還可以繼續執行。在實際專案中,每個子類對應不同的業務含義,使用父類作為引數,傳遞不同的子類完成不同的業務邏輯,非常完美。

看到一句話,白馬是馬,而馬非白馬。

這位仁兄的部落格寫得也真是有意思了。貼個連線方便以後溫習。點選開啟連結

裡面提到,正方形不可以是正方形的子類,舉例深明,淺顯易懂。

public class Rectangle extends Quadrangle {
    private long width;
    private long height;

    public void setWidth(long width) {
        this.width = width;
    }

    public long getWidth() {
        return this.width;
    }

    public void setHeight(long height) {
        this.height = height;
    }

    public long getHeight() {
        return this.height;
    }
}
package com.designphilsophy.lsp.version2;

/**
 * 自己宣告height和width
 * @author xingjiarong
 *
 */
public class Square extends Quadrangle 
{
    private long width;
    private long height;

    public void setWidth(long width) {
        this.height = width;
        this.width = width;
    }

    public long getWidth() {
        return width;
    }

    public void setHeight(long height) {
        this.height = height;
        this.width = height;
    }

    public long getHeight() {
        return height;
    }
}

此時呼叫smart,顯然正方形的情況出現了bug,會一直long下去。

今日做筆記的時候,順帶一搜還真有個知乎相關的問題。是這麼說的:微笑

JAVA中,多型是不是違背了里氏替換原則??

里氏替換原則要求子類避免重寫父類方法,而多型的條件之一卻是要求子類重寫父類的方法。所以,我搞不懂里氏替換原則與繼承,多型之間的關係。這是問題 這是某位古道熱腸的程式猿給的回答,居然關心起機器人的生娃問題,這麼一想,這個原則還真是頗有哲學氣息,竟涵蓋了詭辯,數學,電子技術(計算機程式設計)各個方面,實在是重要的很啊。

相關推薦

關於里氏替換原則概念糾正

public abstract class Quadrangle{ protected abstract void getWidth(); protected abstract void getHeight(); } public class Rectangle exten

開閉原則里氏替換原則

1.開閉原則是面向物件設計的基本原則之一,是“可複用設計”的基礎,它的主要原則是:對擴充套件開放,對修改關閉;意思就是我們改變一個軟體時。應該通過擴充套件方式來改變軟體,而不是修改原有的程式碼。2.里氏替換原則里氏替換原則是說,任何基類可以出現的地方,子類一定可以出現(只有當

設計模式 - 七大設計原則(三)- 迪米特法則里氏替換原則

概述 簡單介紹一下七大設計原則: 開閉原則:是所有面向物件設計的核心,對擴充套件開放,對修改關閉 依賴倒置原則:針對介面程式設計,依賴於抽象而不依賴於具體 單一職責原則:一個介面只負責一件事情,只能有一個原因導致類變化 介面隔離原則:使用多個專門的介面,而不是使用一個總介面 迪米特法則(最少知道原則):

計算各種圖形的周長(介面)---Java

Problem Description 定義介面Shape,定義求周長的方法length()。 定義如下類實現介面Shape的抽象方法: (1)三角形類Triangle (2)長方形類Rectangle (3)圓形類Circle等。 定義測試類ShapeTest,用Shape介面定義

繼承動手動腦總結

一:繼承條件下的構造方法呼叫 程式程式碼: class Grandparent { public Grandparent() { System.out.println("GrandParent Created."); } pub

關於繼承的簡單認識

(1)繼承條件下的構造方法呼叫 package Demo1; class Grandparent { public Grandparent() { System.out.println("GrandParent Created.");

03繼承 動手動腦

動手實驗:繼承條件下的構造方法呼叫 執行 TestInherits.java 示例,觀察輸出,注意總結父類與子類之間構造方法的呼叫關係修改Parent構造方法的程式碼,顯式呼叫GrandParent的另一個建構函式,注意這句呼叫程式碼是否是第一句,影響重大! class Grandp

第10章 介面、繼承

10.1 package tex; public abstract class one { abstract void test(); public static void main(String args[]) { new one(); } } //無法例項化 10.2 p

面向物件【林老師版】:性(十三)

一、多型 多型指的是一類事物有多種形態,比如 1、動物有多種形態:人,狗,豬 import abc class Animal(metaclass=abc.ABCMeta): #同一類事物:動物 @abc.abstractmethod def talk(self):

第2章 面向物件的設計原則(SOLID):2_里氏替換原則(LSP)

2. 里氏替換原則(Liskov Substitution Principle,LSP) 2.1 定義 (1)所有使用基類的地方必須能透明地使用子類替換,而程式的行為沒有任何變化(不會產生執行結果錯誤或異常)。只有這樣,父類才能被真正複用,而且子類也能夠在父類的基礎上增加新的行為。也只有這樣

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

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

Java面向物件----概念,物件上下轉型

概念:同一操作作用於某一類物件,可以有不同的解釋,產生不同的執行結果 多型存在的三個必要條件   需要存在繼承和實現關係   同樣的 方法呼叫而執行不同操作,執行不同的程式碼(重寫操作)   在執行時父類或者介面的引用變數可以引用其子類的 物件 package com.tanle

小白學python之繼承_學習筆記

本文以廖雪峰的官方網站為參考來學習python的。其學習連結為廖雪峰小白學python教程。 本文是學習到python的繼承與多型。參考連結廖雪峰python繼承與多型。 class Animal(object): def run(self): print('Anim

繼承的一個簡單例項

程式結構: 父為Person類,Person類個子類Student和Employee,Employee類又有兩個子類,Staff和Faculty。 繼承即子類可以繼承父類的資料域和方法: Student類和Employee類繼承了Person類的資料域name,address pho

Python:父類的繼承

#父類的多繼承 例:孩子繼承父親以及母親的屬性 #父親屬性 class Father(object) : def __init__(self,money): self.money = money def Running(self): pri

虛擬函式知識點總結

虛擬函式和多型 1:多型性是指一個名字,多種語義;或介面相同,多種實現。 2:虛擬函式允許函式呼叫與函式體的聯絡在執行時才進行,稱為動態聯編。 3:實現執行時多型的關鍵首先是要說明虛擬函式,另外,必須用類指標呼叫派生類的不同實現版本 4:注意點: ①:一個虛擬函式,在派生類層介面相同的過載

C++設計模式-繼承影響耦合性(最基礎的簡單工廠模式小例項)

繼承與多型影響耦合性(最基礎的簡單工廠模式小例項) 原理: 通過繼承和虛擬函式的方式修改某個子類對應函式的功能; 通過簡單工廠模式到底例項化誰; 如果要增加複雜的運算只有增加響應的子類,以及工廠的分支即可;   程式執行截圖如下:   目錄結構如

Java繼承、覆寫

1.繼承的定義與使用 繼承的主要作用在於:在已有基礎上繼續進行功能的擴充(可重用) 繼承能夠消除結構定義上的重複 1.1繼承的實現 繼承使用extends關鍵字來實現 class 子類 extends 父類 Java是單繼承 : 一個子類只有一個父

virtual、abstract、override

abstract與override using System; public class Test { public static void Main() { Animal dog = new Dog("dog"); Anima

c++三大特性(繼承,封裝,)及過載的區別。

    封裝可以隱藏實現細節,使得程式碼模組化,繼承可以擴充套件已存在的模組,它們目的都是為了:程式碼重用。而多型是為了實現另一個目的:介面重用。     封裝是面向物件的特徵之一,是物件和類概念的主要特性。封裝是把過程和資料包圍起來,