国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

設(shè)計(jì)原則學(xué)習(xí)之里氏替換原則

這篇具有很好參考價(jià)值的文章主要介紹了設(shè)計(jì)原則學(xué)習(xí)之里氏替換原則。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

以下內(nèi)容均來自抖音號(hào)【it楠老師教java】的設(shè)計(jì)模式課程。

1、原理概述

子類對象(objectofsubtype/derivedclass)能夠替換程序(program)中父類對象(objectofbase/parentclass)出現(xiàn)的任何地方,并且保證原來程序的邏輯行為(behavior)不變及正確性不被破壞。

2、簡單的示例1

// 基類:鳥類
public class Bird {
public void fly () {
System . out . println ( "I can fly" );
} }
// 子類:企鵝類
public class Penguin extends Bird {
// 企鵝不能飛,所以覆蓋了基類的 fly 方法,但這違反了里氏替換原則
public void fly () {
throw new UnsupportedOperationException ( "Penguins can't fly" );
}
}
為了遵循LSP,我們可以重新設(shè)計(jì)類結(jié)構(gòu),將能飛的行為抽象到一個(gè)接口中,讓需要飛行能力的鳥類實(shí)現(xiàn)這個(gè)接口:
// 飛行行為接口
public interface Flyable {
void fly ();
}
// 基類:鳥類
public class Bird {
}
// 子類:能飛的鳥類
public class FlyingBird extends Bird implements Flyable {
@Override
public void fly () {
System . out . println ( "I can fly" );
}
}
// 子類:企鵝類,不實(shí)現(xiàn) Flyable 接口
public class Penguin extends Bird {
}

這里就該明確那些方法是通用的,哪些方法是部分能用的。

比如通用的方法可以放到class bird里。

public void say(){ System.out.println("我屬于鳥科")}

public void say(){ System.out.println("我又一雙翅膀,盡管不能飛")}

不同的用的方法,可以放到接口里比如有的鳥很小 有的鳥很大

interface? BigBird{ double height()}

interface? SmallBird{ double height()}

上述可能不太準(zhǔn)確,但是核心思想就是抽取公共的方法到類里,抽取特殊的方法到接口里。

再舉個(gè)例 比如

class? door{

//核心方法 只要是門 不管你啥樣的 你肯定又面積吧,有價(jià)格吧

int price();

int area();

}

但是有的門市防火門 有的是防盜門, 有的是....

interface FangHuo{ void canFangHuo()};

interface FangDao{ void canFangDao()};

3、示例2

我們再來看一個(gè)基于數(shù)據(jù)庫操作的案例。假設(shè)我們正在開發(fā)一個(gè)支持多種數(shù)據(jù)庫的程序,包括MySQL、PostgreSQL和SQLite。我們可以使用里氏替換原則來設(shè)計(jì)合適的類結(jié)構(gòu),確保代碼的可維護(hù)性和擴(kuò)展性。 首先,我們定義一個(gè)抽象的Database 基類,它包含一些通用的數(shù)據(jù)庫操作方法, 如 connect() 、disconnect() 和 executeQuery() 。這些方法的具體實(shí)現(xiàn)將在 子類中完成。

public abstract class Database {
public abstract void connect ();
public abstract void disconnect ();
public abstract void executeQuery ( String query );
}

然后,為每種數(shù)據(jù)庫類型創(chuàng)建一個(gè)子類,繼承自 Database 基類。這些子類需要實(shí)現(xiàn)基類中定義的抽象方法,并可以添加特定于各自數(shù)據(jù)庫的方法。

這里新手要思考下 為什么用abstract class 怎么不用class 怎么不用interface

不用class,因?yàn)槲疫@里還沒有具體到那類數(shù)據(jù)源,其實(shí)可以定義個(gè)jdbcDatabase ,定義屬性driver,url,user ,password。就是更一部的抽取

不用interface 因?yàn)閏onnect close 和query是所有數(shù)據(jù)源都有操作!??!

public class MySQLDatabase extends Database {
@Override
public void connect () {
// 實(shí)現(xiàn) MySQL 的連接邏輯
}
@Override
public void disconnect () {
// 實(shí)現(xiàn) MySQL 的斷開連接邏輯
}
@Override
public void executeQuery ( String query ) {
// 實(shí)現(xiàn) MySQL 的查詢邏輯
}
// 其他針對 MySQL 的特定方法
}
public class PostgreSQLDatabase extends Database {
// 類似地,為 PostgreSQL 實(shí)現(xiàn)相應(yīng)的方法
}
public class SQLiteDatabase extends Database {
// 類似地,為 SQLite 實(shí)現(xiàn)相應(yīng)的方法
}

?

這樣設(shè)計(jì)的好處是,我們可以在不同的數(shù)據(jù)庫類型之間靈活切換,而不需要修改大量代碼。只要這些子類遵循里氏替換原則,我們就可以放心地使用基類的引用來操作不同類型的數(shù)據(jù)庫。例如:?

public class DatabaseClient {
private Database database ;
public DatabaseClient ( Database database ) {
this . database = database ;
}
public void performDatabaseOperations () {
database . connect ();
database . executeQuery ( "SELECT * FROM users" );
database . disconnect ();
}
}
public class Main {
public static void main ( String [] args ) {
// 使用 MySQL 數(shù)據(jù)庫
DatabaseClient client1 = new DatabaseClient ( new MySQLDatabase ());
client1 . performDatabaseOperations ();
// 切換到 PostgreSQL 數(shù)據(jù)庫
DatabaseClient client2 = new DatabaseClient ( new PostgreSQLDatabase ());
client2 . performDatabaseOperations ();
// 切換到 SQLite 數(shù)據(jù)庫
DatabaseClient client3 = new DatabaseClient ( new SQLiteDatabase ());
client3 . performDatabaseOperations ();
}
}

好了,我們稍微總結(jié)一下。雖然從定義描述和代碼實(shí)現(xiàn)上來看,多態(tài)和里式替換有點(diǎn)類似,但它們關(guān)注的角度是不一樣的。多態(tài)是面向?qū)ο缶幊痰囊淮筇匦?,也是面向?qū)ο缶幊陶Z言的一種語法。它是一種代碼實(shí)現(xiàn)的思路。而里式替換是一種設(shè)計(jì)原則,是用來指導(dǎo)繼承關(guān)系中子類該如何設(shè)計(jì)的,子類的設(shè)計(jì)要保證在替換父類的時(shí)候,不改變原有程序的邏輯以及不破壞原有程序的正確性。?

2 、哪些代碼明顯違背了 LSP
1.子類覆蓋或修改了基類的方法

當(dāng)子類覆蓋或修改基類的方法時(shí),可能導(dǎo)致子類無法替換基類的實(shí)例而不引起問題。這違反了LSP,會(huì)導(dǎo)致代碼變得脆弱和不易維護(hù)。

public class Bird {
public void fly () {
System . out . println ( "I can fly" );
}
}
public class Penguin extends Bird {
@Override
public void fly () {
throw new UnsupportedOperationException ( "Penguins can't fly" );
}
}
在這個(gè)例子中, Penguin 類覆蓋了 Bird 類的 fly() 方法,拋出了一個(gè)異常。這違反了LSP,因?yàn)楝F(xiàn)在 Penguin 實(shí)例無法替換 Bird 實(shí)例而不引發(fā)問題。

?

2、子類違反了基類的約束條件

當(dāng)子類違反了基類中定義的約束條件(如輸入、輸出或異常等),也會(huì)違反LSP。

public class Stack {
private int top ;
private int [] elements ;
public Stack ( int size ) {
elements = new int [ size ];
top = - 1 ;
}
public void push ( int value ) {
if ( top >= elements . length - 1 ) {
throw new IllegalStateException ( "Stack is full" );
} elements [ ++ top ] = value ;
}
public int pop () {
if ( top < 0 ) {
throw new IllegalStateException ( "Stack is empty" );
}
return elements [ top -- ];
}
}
// 正數(shù)的棧
public class NonNegativeStack extends Stack {
public NonNegativeStack ( int size ) {
super ( size );
}
@Override
public void push ( int value ) {
if ( value < 0 ) {
throw new IllegalArgumentException ( "Only non-negative values are allowed" );
}
super . push ( value );
}
}
// 正確的寫法
public class NonNegativeStack extends Stack {
public NonNegativeStack ( int size ) {
super ( size );
}
public void pushNonNegative ( int value ) {
if ( value < 0 ) {
throw new IllegalArgumentException ( "Only non-negative values are allowed" );
}
super . push ( value );
}
}

這里感覺給的資料有問題。。。等我看完視頻在說?文章來源地址http://www.zghlxwxcb.cn/news/detail-624353.html

到了這里,關(guān)于設(shè)計(jì)原則學(xué)習(xí)之里氏替換原則的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 設(shè)計(jì)原則學(xué)習(xí)之里氏替換原則

    以下內(nèi)容均來自抖音號(hào)【it楠老師教java】的設(shè)計(jì)模式課程。 1 、原理概述 子類對象(objectofsubtype/derivedclass)能夠替換程序(program)中父類對象(objectofbase/parentclass)出現(xiàn)的任何地方,并且保證原來程序的邏輯行為(behavior)不變及正確性不被破壞。 2、簡單的示例1 // 基類:

    2024年02月14日
    瀏覽(19)
  • 設(shè)計(jì)模式:里氏代換原則(Liskov Substitution Principle,LSP)介紹

    里氏代換原則(Liskov Substitution Principle,LSP)是面向?qū)ο笤O(shè)計(jì)原則的一部分,它強(qiáng)調(diào) 子類對象應(yīng)該能夠替換其父類對象而不影響程序的正確性 。換句話說,子類對象應(yīng)該可以在不改變程序正確性的前提下替換掉父類對象。 該原則的實(shí)現(xiàn)原理可以通過以下幾點(diǎn)來說明: 子類必

    2024年04月29日
    瀏覽(15)
  • 深入理解設(shè)計(jì)原則之里氏替換原則(LSP)【軟件架構(gòu)設(shè)計(jì)】

    深入理解設(shè)計(jì)原則之里氏替換原則(LSP)【軟件架構(gòu)設(shè)計(jì)】

    C++高性能優(yōu)化編程系列 深入理解軟件架構(gòu)設(shè)計(jì)系列 深入理解設(shè)計(jì)模式系列 高級(jí)C++并發(fā)線程編程 里氏替換原則(Liskov Substitution Principle, LSP)于1986年有Barbara Liskov提出,他當(dāng)時(shí)是這樣描述這條原則的: 如果S是T的子類型,那么T的對象可以被S的對象所替換,并不影響代碼的運(yùn)行

    2024年02月07日
    瀏覽(23)
  • 基于面向?qū)ο蠡A(chǔ)設(shè)計(jì)——里氏替換原則

    基于面向?qū)ο蠡A(chǔ)設(shè)計(jì)——里氏替換原則

    在Java中,支持抽象和多態(tài)的關(guān)鍵機(jī)制之一是繼承。正是使用了繼承,我們才可以創(chuàng)建實(shí)現(xiàn)父類中抽象方法的子類。那么,是什么規(guī)則在支配著這種特殊的繼承用法呢?最佳的繼承層次的特征又是什么呢?在什么情況下會(huì)使我們創(chuàng)建的類層次結(jié)構(gòu)掉進(jìn)不符合開閉原則的陷阱中呢

    2024年02月14日
    瀏覽(25)
  • 里氏替換原則究竟如何理解?

    介 紹 里 氏 替 換 原 則 的 文 章 非 常 多 , 但 可 能 大 家 看 完 之 后 , 心 中 仍 然 留 有 疑 問 , 如 何 去 落 地 實(shí) 現(xiàn) , 如 何 判 斷 是 否 影 響 程 序 功 能 。 本 文 將 帶 領(lǐng) 大 家 深 入 理 解 里 氏 替 換 , 一 起 領(lǐng) 略 下 它 的 真 正 面 目 。 但 在 此 之 前 , 有 必

    2024年02月08日
    瀏覽(26)
  • 里氏替換原則

    里氏替換原則 OOP(Object Oriented Programming) 面向?qū)ο缶幊?OO中的繼承性的思考 1.繼承包含這樣一層含義,父類中凡是已經(jīng)寫好的方法,實(shí)際上就是設(shè)定規(guī)范。雖然不強(qiáng)制要求所有子類必須遵守規(guī)范(不重寫方法),但是如果子類對這些方法,任意修改就會(huì)對繼承體系造成破壞。 2.繼

    2024年02月11日
    瀏覽(33)
  • (學(xué)習(xí)打卡2)重學(xué)Java設(shè)計(jì)模式之六大設(shè)計(jì)原則

    (學(xué)習(xí)打卡2)重學(xué)Java設(shè)計(jì)模式之六大設(shè)計(jì)原則

    ???前言:聽說有本很牛的關(guān)于Java設(shè)計(jì)模式的書——重學(xué)Java設(shè)計(jì)模式,然后買了(*^▽^*) 開始跟著小傅哥學(xué)Java設(shè)計(jì)模式吧,本文主要記錄筆者的學(xué)習(xí)筆記和心得。 打卡!打卡! 單一職責(zé)原則、開閉原則、里氏替換原則、迪米特法則、接口隔離原則、依賴倒置原則。 (引讀:

    2024年02月03日
    瀏覽(29)
  • Spring學(xué)習(xí)筆記(二)Spring的控制反轉(zhuǎn)(設(shè)計(jì)原則)與依賴注入(設(shè)計(jì)模式)

    是一種設(shè)計(jì)原則,降低程序代碼之間的耦合度 對象由Ioc容器統(tǒng)一管理,當(dāng)程序需要使用對象時(shí)直接從IoC容器中獲取。這樣對象的控制權(quán)就從應(yīng)用程序轉(zhuǎn)移到了IoC容器 依賴注入是一種消除類之間依賴關(guān)系的設(shè)計(jì)模式。例如,A類要依賴B類,A類不再直接創(chuàng)建B類,而是把這種依賴

    2024年02月19日
    瀏覽(22)
  • 【設(shè)計(jì)模式】設(shè)計(jì)原則-開閉原則

    定義 作用 1、方便測試;測試時(shí)只需要對擴(kuò)展的代碼進(jìn)行測試。 2、提高代碼的可復(fù)用性;粒度越小,被復(fù)用的可能性就越大。 3、提高軟件的穩(wěn)定性和延續(xù)性,易于擴(kuò)展和維護(hù)。 實(shí)現(xiàn)方式 通過“抽象約束、封裝變化”來實(shí)現(xiàn)開閉原則。通過接口或者抽象類為軟件實(shí)體定義一

    2024年02月15日
    瀏覽(24)
  • 前端設(shè)計(jì)模式和設(shè)計(jì)原則之設(shè)計(jì)原則

    1 開閉原則 該原則指出軟件實(shí)體(類、模塊、函數(shù)等)應(yīng)該 對擴(kuò)展開放,對修改關(guān)閉 。也就是說,在添加新功能時(shí),應(yīng)該通過擴(kuò)展現(xiàn)有代碼來實(shí)現(xiàn),而不是直接修改已有的代碼。這樣可以確?,F(xiàn)有代碼的穩(wěn)定性,并且減少對其他部分的影響。 在上述例子中,有一個(gè)原始功能

    2024年02月07日
    瀏覽(51)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包