日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【思考】再谈面向过程与面向对象

發(fā)布時間:2023/12/20 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【思考】再谈面向过程与面向对象 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.


【思考】再談面向過程與面向?qū)ο?

在我博客創(chuàng)作早期,寫了一篇博文,名字是【Java核心技術(shù)卷】面向過程與面向?qū)ο髮Ρ取?/p>

這篇文章試圖對比描述了關(guān)于 面向過程與面向?qū)ο?/strong> 的內(nèi)容。為什么還要再談呢?

一方面原因是深度不夠,另一方面原因要從對各種編程語言的感知說起 (涵蓋面向?qū)ο?、面向過程):

  • 編譯執(zhí)行的C語言是靜態(tài)語言、弱類型語言。
  • 解釋執(zhí)行的JavaScript語言是動態(tài)語言、弱類型語言。
  • 混合編譯執(zhí)行的Java是靜態(tài)語言、強(qiáng)類型語言。

如果你不太明白靜態(tài)語言和動態(tài)語言以及強(qiáng)類型與弱類型,看文末的補(bǔ)充內(nèi)容。

似乎有很多獨(dú)特的“語言”,而且每一種語言背后都有非常深的“技術(shù)”蘊(yùn)含其中。

之前也曾就C語言,Java,Python,JavaScript這四種語言對比過它們的跨平臺能力,翻譯成機(jī)器碼執(zhí)行的過程,詳情參見【Java核心技術(shù)卷】面向?qū)ο笈c面向過程語言對比

為了幫助你復(fù)習(xí)一遍,這里僅僅展示文章里面的四張圖:

? C語言

? Java語言

? JavaScript語言

? Python語言

但是無論是 面向過程,還是面向?qū)ο?#xff0c; 肯定都有相通之處,也有區(qū)別所在。

面向過程就不多說,基本是C的天下了。

那么對于面向?qū)ο竽?#xff1f;

? 我們這里首先談?wù)撘幌旅嫦驅(qū)ο蟮南嗤ㄖ?#xff1a;

?
面向?qū)ο笥兄蠡咎卣?/p>

  • 封裝
  • 繼承
  • 多態(tài)
  • 這個你就比較熟悉了。

    封裝:
    把客觀事物封裝成抽象的類,并且類可以把自己的數(shù)據(jù)和方法只讓可信的類或者對象操作,對不可信的進(jìn)行信息隱藏。
    類將成員變量和成員函數(shù)封裝在類的內(nèi)部,根據(jù)需要設(shè)置訪問權(quán)限,通過成員函數(shù)管理內(nèi)部狀態(tài)。

    繼承:
    繼承所表達(dá)的是類之間相關(guān)的關(guān)系,這種關(guān)系使得對象可以繼承另外一類對象的特征和能力。
    繼承的作用:避免公用代碼的重復(fù)開發(fā),減少代碼和數(shù)據(jù)冗余。

    多態(tài)
    多態(tài)性可以簡單地概括為“一個接口,多種方法”,字面意思為多種形態(tài)。程序在運(yùn)行時才決定調(diào)用的函數(shù),它是面向?qū)ο缶幊填I(lǐng)域的核心概念。

    但是插句題外話,你知道你所熟悉的語言的"繼承"與“多態(tài)”是如何實(shí)現(xiàn)的嘛?
    關(guān)于Java的話可以參考這三篇文章
    【Java核心技術(shù)卷】了解Java的內(nèi)存邏輯對象模型
    【Java核心技術(shù)卷】理解Java的繼承與多態(tài)重要概念
    【Java核心技術(shù)卷】深入理解Java的動態(tài)綁定,靜態(tài)綁定和多態(tài)

    ?
    不知道你是否學(xué)過設(shè)計(jì)模式的相關(guān)內(nèi)容,像UML、七大軟件設(shè)計(jì)原則、二十三種設(shè)計(jì)模式 它們中有很多的東西都是面向?qū)ο笏ㄓ玫?#xff0c;里面深刻地體現(xiàn)著面向?qū)ο蟮乃枷搿?/p>

    有一句話說的很好:“使用設(shè)計(jì)模式的目的:為了代碼可重用性、讓代碼更容易被他人理解、保證代碼可靠性。 設(shè)計(jì)模式使代碼編寫真正工程化;設(shè)計(jì)模式是軟件工程的基石脈絡(luò),如同大廈的結(jié)構(gòu)一樣”

    建議每個人都要好好琢磨琢磨。

    ?
    那你聽說過面向?qū)ο蟮奈宕蠡驹瓌t嗎?

  • 單一職責(zé)原則(Single-Responsibility Principle)
  • 開放封閉原則(Open-Closed principle)
  • Liskov替換原則(Liskov-Substituion Principle)
  • 依賴倒置原則(Dependency-Inversion Principle)
  • 接口隔離原則(Interface-Segregation Principle)
  • 其實(shí)這五條也是七大軟件設(shè)計(jì)原則中的內(nèi)容,我們看吧~

    七大軟件設(shè)計(jì)原則 可以參考【Java設(shè)計(jì)模式】軟件設(shè)計(jì)七大原則
    實(shí)現(xiàn)語言是 Java哈,因?yàn)橛信e例所以更好理解一些。


    面向?qū)ο蟮奈宕蠡驹瓌t 文字?jǐn)⑹霾糠?/h5>

    這部分內(nèi)容參考了網(wǎng)上的資料,但是因?yàn)閬碓催^多,無法注明出處了。

    一、 單一職責(zé)原則(Single-Resposibility Principle)

    其核心思想為:一個類,最好只做一件事,只有一個引起它的變化。

    單一職責(zé)原則可以看做是低耦合、高內(nèi)聚在面向?qū)ο笤瓌t上的引申,將職責(zé)定義為引起變化的原因,以提高內(nèi)聚性來減少引起變化的原因。

    職責(zé)過多,可能引起它變化的原因就越多,這將導(dǎo)致職責(zé)依賴,相互之間就產(chǎn)生影響,從而大大損傷其內(nèi)聚性和耦合度。

    通常意義下的單一職責(zé),就是指只有一種單一功能,不要為類實(shí)現(xiàn)過多的功能點(diǎn),以保證實(shí)體只有一個引起它變化的原因。

    單一是一個類的優(yōu)良設(shè)計(jì)。交雜不清的職責(zé)將使得代碼看起來特別別扭牽一發(fā)而動全身,有失美感和必然導(dǎo)致丑陋的系統(tǒng)錯誤風(fēng)險(xiǎn)。

    二、開放封閉原則(Open-Closed principle)

    其核心思想是:軟件實(shí)體應(yīng)該是可擴(kuò)展的,而不可修改的。也就是,對擴(kuò)展開放,對修改封閉的。

    開放封閉原則主要體現(xiàn)在兩個方面:
    1、對擴(kuò)展開放,意味著有新的需求或變化時,可以對現(xiàn)有代碼進(jìn)行擴(kuò)展,以適應(yīng)新的情況。
    2、對修改封閉,意味著類一旦設(shè)計(jì)完成,就可以獨(dú)立完成其工作,而不要對其進(jìn)行任何嘗試的修改。

    實(shí)現(xiàn)開開放封閉原則的核心思想就是對抽象編程,而不對具體編程,因?yàn)槌橄笙鄬Ψ€(wěn)定。讓類依賴于固定的抽象,所以修改就是封閉的;而通過面向?qū)ο蟮睦^承和多態(tài)機(jī)制,又可以實(shí)現(xiàn)對抽象類的繼承,通過覆寫其方法來改變固有行為,實(shí)現(xiàn)新的拓展方法,所以就是開放的。

    “需求總是變化”沒有不變的軟件,所以就需要用封閉開放原則來封閉變化滿足需求,同時還能保持軟件內(nèi)部的封裝體系穩(wěn)定,不被需求的變化影響。

    三、Liskov替換原則(Liskov-Substituion Principle)

    其核心思想是:子類必須能夠替換其基類。

    這一思想體現(xiàn)為對繼承機(jī)制的約束規(guī)范,只有子類能夠替換基類時,才能保證系統(tǒng)在運(yùn)行期內(nèi)識別子類,這是保證繼承復(fù)用的基礎(chǔ)。

    在父類和子類的具體行為中,必須嚴(yán)格把握繼承層次中的關(guān)系和特征,將基類替換為子類,程序的行為不會發(fā)生任何變化。同時,這一約束反過來則是不成立的,子類可以替換基類,但是基類不一定能替換子類。

    Liskov替換原則,主要著眼于對抽象和多態(tài)建立在繼承的基礎(chǔ)上,因此只有遵循了Liskov替換原則,才能保證繼承復(fù)用是可靠地。

    實(shí)現(xiàn)的方法是面向接口編程:將公共部分抽象為基類接口或抽象類,通過Extract Abstract Class,在子類中通過覆寫父類的方法實(shí)現(xiàn)新的方式支持同樣的職責(zé)。

    Liskov替換原則是關(guān)于繼承機(jī)制的設(shè)計(jì)原則,違反了Liskov替換原則就必然導(dǎo)致違反開放封閉原則。

    Liskov替換原則能夠保證系統(tǒng)具有良好的拓展性,同時實(shí)現(xiàn)基于多態(tài)的抽象機(jī)制,能夠減少代碼冗余,避免運(yùn)行期的類型判別。

    四、 依賴倒置原則(Dependecy-Inversion Principle)

    其核心思想是:依賴于抽象。具體而言就是高層模塊不依賴于底層模塊,二者都同依賴于抽象;抽象不依賴于具體,具體依賴于抽象。

    我們知道,依賴一定會存在于類與類、模塊與模塊之間。當(dāng)兩個模塊之間存在緊密的耦合關(guān)系時,最好的方法就是分離接口和實(shí)現(xiàn):在依賴之間定義一個抽象的接口使得高層模塊調(diào)用接口,而底層模塊實(shí)現(xiàn)接口的定義,以此來有效控制耦合關(guān)系,達(dá)到依賴于抽象的設(shè)計(jì)目標(biāo)。

    抽象的穩(wěn)定性決定了系統(tǒng)的穩(wěn)定性,因?yàn)槌橄笫遣蛔兊?#xff0c;依賴于抽象是面向?qū)ο笤O(shè)計(jì)的精髓,也是依賴倒置原則的核心。

    依賴于抽象是一個通用的原則,而某些時候依賴于細(xì)節(jié)則是在所難免的,必須權(quán)衡在抽象和具體之間的取舍,方法不是一層不變的。依賴于抽象,就是對接口編程,不要對實(shí)現(xiàn)編程。

    五、接口隔離原則(Interface-Segregation Principle)

    其核心思想是:使用多個小的專門的接口,而不要使用一個大的總接口。

    具體而言,接口隔離原則體現(xiàn)在:接口應(yīng)該是內(nèi)聚的,應(yīng)該避免“胖”接口。一個類對另外一個類的依賴應(yīng)該建立在最小的接口上,不要強(qiáng)迫依賴不用的方法,這是一種接口污染。

    接口有效地將細(xì)節(jié)和抽象隔離,體現(xiàn)了對抽象編程的一切好處,接口隔離強(qiáng)調(diào)接口的單一性。而胖接口存在明顯的弊端,會導(dǎo)致實(shí)現(xiàn)的類型必須完全實(shí)現(xiàn)接口的所有方法、屬性等;而某些時候,實(shí)現(xiàn)類型并非需要所有的接口定義,在設(shè)計(jì)上這是“浪費(fèi)”,而且在實(shí)施上這會帶來潛在的問題,對胖接口的修改將導(dǎo)致一連串的客戶端程序需要修改,有時候這是一種災(zāi)難。在這種情況下,將胖接口分解為多個特點(diǎn)的定制化方法,使得客戶端僅僅依賴于它們的實(shí)際調(diào)用的方法,從而解除了客戶端不會依賴于它們不用的方法。

    分離的手段主要有以下兩種:
    1、委托分離,通過增加一個新的類型來委托客戶的請求,隔離客戶和接口的直接依賴,但是會增加系統(tǒng)的開銷。
    2、多重繼承分離,通過接口多繼承來實(shí)現(xiàn)客戶的需求,這種方式是較好的。

    以上就是5個基本的面向?qū)ο笤O(shè)計(jì)原則,它們就像面向?qū)ο蟪绦蛟O(shè)計(jì)中的金科玉律,遵守它們可以使我們的代碼更加鮮活,易于復(fù)用,易于拓展,靈活優(yōu)雅。不同的設(shè)計(jì)模式對應(yīng)不同的需求,而設(shè)計(jì)原則則代表永恒的靈魂,需要在實(shí)踐中時時刻刻地遵守。就如ARTHUR J.RIEL在那邊《OOD啟示錄》中所說的:“你并不必嚴(yán)格遵守這些原則,違背它們也不會被處以宗教刑罰。但你應(yīng)當(dāng)把這些原則看做警鈴,若違背了其中的一條,那么警鈴就會響起?!?/p>

    為了讓代碼更加完美,我們往往會重構(gòu)它,如果能夠很好遵守這5個基本的面向?qū)ο笤O(shè)計(jì)原則,并且有著良好的單元測試習(xí)慣,那么重構(gòu)將不會一下子變得無比艱難。



    ? 那面向?qū)ο蟮恼Z言的區(qū)別呢?

    這范圍可就廣了,用我熟悉的Java和C++說一下吧,通過對比,我們是能夠?qū)W到東西的:

    ?

    C++ 被設(shè)計(jì)成主要用在系統(tǒng)性應(yīng)用程序設(shè)計(jì)上的語言,對C語言進(jìn)行了擴(kuò)展。對于C語言, C++ 特別加上了以下這些特性的支持:靜態(tài)類型的面向?qū)ο蟪绦蛟O(shè)計(jì)的支持、異常處理、RAII以及泛型。另外它還加上了一個包含泛型容器和算法的C++庫函數(shù)。

    Java 依賴一個虛擬機(jī)來保證安全和可移植性。Java包含一個可擴(kuò)展的庫用以提供一個完整的的下層平臺的抽象。Java是一種靜態(tài)面向?qū)ο笳Z言,它使用的語法類似C++,但與之不兼容。為了使更多的人到使用更易用的語言,它進(jìn)行了全新的設(shè)計(jì)。

    ?

    C++是編譯型語言(首先將源代碼編譯生成機(jī)器語言,再由機(jī)器運(yùn)行機(jī)器碼),執(zhí)行速度快、效率高;依賴編譯器、跨平臺性差些。

    Java是混合型語言(源代碼不是直接翻譯成機(jī)器語言,而是先翻譯成中間代碼,再由解釋器對中間代碼進(jìn)行解釋運(yùn)行。),執(zhí)行速度慢、效率低;依賴解釋器、跨平臺性好。

    ?

    C++是平臺相關(guān)的

    Java是平臺無關(guān)的。

    ?

    C++對所有的數(shù)字類型有標(biāo)準(zhǔn)的范圍限制,但字節(jié)長度是跟具體實(shí)現(xiàn)相關(guān)的,不同操作系統(tǒng)可能。

    Java在所有平臺上對所有的基本類型都有標(biāo)準(zhǔn)的范圍限制和字節(jié)長度。

    ?

    C++除了一些比較少見的情況之外和C語言兼容 。

    Java沒有對任何之前的語言向前兼容。但在語法上受 C/C++ 的影響很大

    ?

    C++允許直接調(diào)用本地的系統(tǒng)庫 。

    Java要通過JNI調(diào)用, 或者 JNA

    ?
    C++允許過程式程序設(shè)計(jì)和面向?qū)ο蟪绦蛟O(shè)計(jì) 。

    Java必須使用面向?qū)ο蟮某绦蛟O(shè)計(jì)方式

    ?

    C++支持指針,引用,傳值調(diào)用 。

    Java只有值傳遞。

    Java只有值傳遞 , 這個 你不好奇嗎?

    ?

    C++需要顯式的內(nèi)存管理,但有第三方的框架可以提供垃圾搜集的支持。支持析構(gòu)函數(shù)。

    Java 是自動垃圾收集的。沒有析構(gòu)函數(shù)的概念。

    ?
    C++支持多重繼承,包括虛擬繼承 。

    Java只允許單繼承,需要多繼承的情況要使用接口。

    千萬不要把自己限制死了,通過比較能拓寬我們的見識。




    最后補(bǔ)充一下上面需要參考的內(nèi)容:

    靜態(tài)類型語言、動態(tài)類型語言分析:

    靜態(tài)類型語言:變量定義時有類型聲明的語言。
    1)變量的類型在編譯的時候確定
    2)變量的類型在運(yùn)行時不能修改
    這樣編譯器就可以確定運(yùn)行時需要的內(nèi)存總量。
    例如:C/C++/Java/C#語言是靜態(tài)類型語言。

    動態(tài)類型語言:變量定義時無類型聲明的語言。
    1)變量的類型在運(yùn)行的時候確定
    2)變量的類型在運(yùn)行可以修改
    例如:Javascript語言是動態(tài)類型語言。
    由于動態(tài)類型和靜態(tài)類型語言的特性衍生出強(qiáng)類型語言和弱類型、無類型語言。

    強(qiáng)類型語言、弱類型、無類型語言:
    弱/強(qiáng)類型指的是語言類型系統(tǒng)的類型檢查的嚴(yán)格程度。弱類型相對于強(qiáng)類型來說類型檢查更不嚴(yán)格,比如說允許變量類型的隱式轉(zhuǎn)換,允許強(qiáng)制類型轉(zhuǎn)換等等。

    • 強(qiáng)類型語言:例如Java/C#語言是強(qiáng)類型語言,強(qiáng)類型定義語言是類型安全的語言,是由編譯器以及編譯器生成的中間代碼來保證類型安全。
    • 弱類型語言:C/C++/Javascript語言是弱類型語言,其類型安全由程序員來保證,Javascript語言的安全由程序員來保證。
      無類型語言:是動態(tài)語言,變量中既可以存放數(shù)據(jù)又可以存放代碼。

    總結(jié)

    以上是生活随笔為你收集整理的【思考】再谈面向过程与面向对象的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。