1. 程式人生 > >淺談面向物件的程式設計思想:如何優雅地把大象裝進冰箱?

淺談面向物件的程式設計思想:如何優雅地把大象裝進冰箱?

這裡寫圖片描述
  許多人剛學程式設計時,想必都聽到過這樣的話:“*語言是面向物件的,而***語言是面向過程的”。那時的新人還懵懵懂懂,就被大牛或者書上的大牛騙去學了一種聽起來很厲害的語言,然而學了半天,也沒搞清楚楚自己面向了什麼,面向物件的還是沒找著物件,面向過程的找物件的過程也都還沒開始。不禁懷疑當年自己說出那句“教練,我想學這個”的時候腦袋裡都進了些什麼。
這裡寫圖片描述
  然而學都學了,花在寫程式碼上的大把青春和大把頭髮終究是要不回來的,心痛之餘,只好再回頭看一自己那麼多年來到底面向了什麼:
  那年春節,宋丹丹問趙本山:“把大象放進冰箱,需要幾步?”——簡單,一位躲在暗處的大佬丟掉手上的菸頭,嘴角微微上揚。只見他在紙上寫道:

第一步,開啟冰箱
第二步,把大象塞進去
第三步,關上冰箱

  一個天衣無縫的解決方案,大佬看著自己的答案,志得意滿。

  這時,一個智者出現了,他看著大佬的答案,問了一個問題:

如果要把兩頭大象分別裝進兩個冰箱裡呢?

  大佬不屑地一笑:

這個問題同樣簡單,只需要將以上過程重複一遍就行了。

  智者聽到這個回答,嘆了口氣,遞給大佬一張圖紙,轉身離去。
  大佬看著這張圖紙,陷入了深思…

誰來開門?——面向過程和麵向物件的根本區別

  大佬的解決方案簡單粗暴,通俗易懂,與早期的純面向過程程式設計有著異曲同工之妙。他們都是將一個問題分解為若干小問題,再將這些小問題一一解決,這個做法看上去非常完美,並且可以解決大多數問題。
  在這一思路的指導下,程式設計師們會逐個開啟冰箱的門,每增多一個冰箱,就去開啟一次門。
  而智者給的圖紙上只有一個冰箱,這個冰箱會自己把門開啟。只要是按照這個圖紙生產出來的冰箱,就可以自己把門開啟,自己把大象裝進去,自己把門關上。人們不需要了解這一過程是如何實現的,只要在需要把大象裝進冰箱的時候,跟冰箱說一句:“嘿,你把大象裝進去吧。”


  像這樣子,在解決問題的過程中,分析出每個參與解決問題的物件(冰箱),並確定這些物件的行為(開門,裝大象,關門),最終由這些物件解決問題的程式設計思想,被稱為面向物件的程式設計思想(Object Oriented Programming,簡稱OOP)。在面向物件程式設計中,這張圖紙就被稱為,而按照這張圖紙生產出來的一臺臺冰箱,則被稱為類的例項或者物件,這一生產過程,就被稱為類的例項化
  也許有人會問:我要這圖紙有何用?我寫個函式,一樣可以實現這個功能,只要在需要開門的時候呼叫這個函式就行了,又何需考慮自動開門的冰箱怎麼設計?
  這個想法固然好,但問題在於,每當冰箱換個型號,我們就要因為其中的微小變動而重寫一遍這個函式。而接下來所介紹的面向物件程式設計的三大特徵,就可以很好地解決面向過程程式設計遇到的一些問題。

大佬也難免犯錯——封裝,讓物件的內部保持安全

  眾所周知,開門是個極為複雜的工作,這一過程涉及到了無數的零部件,即便是大佬,也很難保證在開門的過程中不影響到與之無關的零部件。有時候僅僅是改動到了一個微小的部件,也可能帶來不可估量的影響。在這種時候,我們迫切地需要一種方法,將與開門無關的部件保護起來,以免被大佬改動到。
  這種方法在面向物件程式設計中,被稱為封裝,物件為它內部的資料提供了不同級別的保護,確定了哪些資料只能由誰訪問,通過這樣的方式,我們可以有效地阻止程式執行過程中的某些意外錯誤地修改了無關的資料。

當冰箱的功能不止開門——繼承,讓物件青出於藍而勝於藍

  冰箱的流水線生產終於形成了一定規模,大佬滿意地看著這一成果。
  這時大佬腦袋中突然閃過一個想法:

我們能不能生產出可以調節內部溫度的冰箱呢?

  怎麼辦?要改動原來的圖紙嗎?還是重新畫一張圖紙?
  這時,流水線上的一個工人笑了:

你只需要告訴我們應該增加哪些零件和功能就行了。

  大佬聞言,吃了一驚,手中所執圖紙,不覺落於地下。時正值天雨將至,雷聲大作。大佬乃從容俯首拾圖紙曰:“一震之威,乃至於此。”
  工人無意中道出的,便是面向物件程式設計的第二個基本特徵:繼承。繼承賦予新建立的類一種能力:它可以使用現有類的全部功能,而不需要為了擴充套件現有類的功能而重寫程式碼。正如前面的例子所說,我們要給冰箱設計新的功能,並不需要重新畫一張完整的圖紙,我們只需要設計一張只有新功能的圖紙就行了。在這一過程中,繼承了現有類的新類(新圖紙)被稱為子類派生類,而被繼承的類(原圖紙)被稱為基類父類或者超類
  繼承可以使我們將不同的物件的相同特徵(開門)提取出來,做成一個基類(原圖紙),而其餘的內容則由派生類(新圖紙)來實現,從而大大縮短了程式碼的複雜度,提高了程式設計效率。

如何生產出不同型號的冰箱?——多型,讓物件更加靈活

  隨著冰箱和大象的不斷增多,原有的冰箱已經滿足不了大象們了——大佬需要更多不同型號的冰箱,但問題來了:對於不同型號的冰箱,我們是不是還能再接著說出和“嘿,你把大象裝進去吧。”一模一樣的話呢?
  在現實世界中,這一切似乎順理成章,但在不支援面向物件程式設計的語言中,我們不得不改動這句話,因為在這些語言中,函式的名稱不能相同。
  這時候,面嚮物件語言提供的多型,正好解決了這一問題。多型是指,當我們要做一件目的相同的事(開門),但必須採用不同方法時,我們可以用同樣的方式來呼叫它們(向冰箱說同樣的話),從而統一了這些過程的呼叫方式,提高了程式碼的可讀性。

沒有銀彈——不要為了面向物件而面向物件

  縱然面向物件程式設計可以給我們帶來諸多的便利,但請切記:它始終只是解決問題的無數方法中的一種,而不是唯一一種。並非所有問題都不得不用面向物件的方法解決,應該首先明確需要解決的問題,而非首先考慮解決問題的方法。避免無意義的封裝,繼承和多型,否則你的程式將會變得一團糟。
  Fred Brooks在他最著名的隨筆《No Silver Bullet》中提到,任何神奇的理論或方法,都不是能殺死軟體危機這頭人狼的銀彈,在軟體開發過程裡是沒有萬能的武器的,只有各種方法綜合運用,才是真正的解決之道。
這裡寫圖片描述

參考資料:

相關推薦

面向物件程式設計思想如何優雅大象冰箱

  許多人剛學程式設計時,想必都聽到過這樣的話:“*語言是面向物件的,而***語言是面向過程的”。那時的新人還懵懵懂懂,就被大牛或者書上的大牛騙去學了一種聽起來很厲害的語言,然而學了半天,也沒搞清楚楚自己面向了什麼,面向物件的還是沒找著物件,面向過程的找物件

面向物件程式設計

1. OOP簡介 面向物件程式設計(object-oriented programming)以下統一簡稱為OOP。世界上第一個OOP語言叫Simula,誕生於20世紀60年代,是它引入了物件、類、繼承、虛過程等等這些概念。當時還沒有“object-oriented”

面向物件程式設計和麵向過程(一)

       今天小編被老師點名叫起來回答“來說說面向物件是什麼”,“不知道”,“那面向過程呢?”,“不知道”,“這麼直接?你下次好好聽聽,明天接著問你。”嘛,今天已經快過去了,那我們就趁著晚自習的時候,好好來總結一下,什麼面向物件,什麼是面向過程,為什麼會有面向物件這個東

大象冰箱HTTP傳輸大檔案的方法

上次我們談到了HTTP報文裡的div,知道了HTTP可以傳輸很多種類的資料,不僅是文字,也能傳輸圖片,音訊和視訊。   早期網際網路上傳輸的基本上都是隻有幾k大小的文字和小圖片,現在的情況則大有不同。網頁裡包含的資訊實在太多了,隨隨便便一個主頁HTML就有可能上百K,高質量的圖片都以M論,更不要

CoreJava學習第五課 --- 進入第二階段面向物件程式設計思想

面向物件程式設計思想 1.面向過程 ​ 從計算機執行角度出發 ,程式碼執行過程核心為從程式的執行過程出發,構建程式設計思路,例: 哥德巴赫猜想 // 面向過程 1 使用者輸入一個數n 2 驗證數字的正確性 2.1 正確就繼續向下

面向物件中的一些主要思想

淺談面向物件中的一些主要思想 何為OOP OOP是一種思想,即為面向物件程式設計,將資料和行為進行封裝並看作物件進行操作,這一點很多資料書籍都提過,OOP的核心是一種思想,是解決實際問題時需要的一種思考方式,在這裡,我想以一個例子切入,來談一談的對與OOP的理解。 人作為現實生活中的一個實體,我們可以很直觀的

C++Primer_Chap15_面向物件程式設計_List01_OOP概述_筆記

面向物件程式設計(object-oriented programming)的核心思想是資料抽象、繼承和動態繫結。   使用資料抽象,可以將類的介面與實現分離   使用繼承,可以定義相似的型別並對其相似關係建模   使用動態繫結,可以一定程度上忽略相似型別的區

關於Java基礎的複習總結(五)面向物件特徵

種下一棵樹,最好的時間是十年前,其次就是現在 面向物件三大特徵 封裝:保證物件自身資料的完整性和安全性 繼承:建立類之間的關係,實現程式碼複用,方便系統擴充套件 多型:相同的方法呼叫,不同的實現方式 PS:抽象也是面向物件思想重要部分,但因為各種程式語言都使用抽象,所以,不能算java

Java面向物件程式設計思想(一)

宣告:學基礎,在校學生,本文所有內容來自純書本,然後通過自己的理解和參考編寫而來,如有說的不對的地方,歡迎評論指錯!(僅做學習交流) 類和物件的建立 類的建立:(public private protected)+ class + 類名 { <類

JS面向物件程式設計封裝、繼承、多型

          一、封裝       (1)封裝通俗的說,就是我有一些祕密不想讓人知道,就通過私有化變數和私有化方法,這樣外界就訪問不到了。然後如果你有一些很想讓大家知道的東西,你就可以通

面向物件程式設計的可替代性

面向物件程式設計是基於”事物屬性和方法有共性”的前提下才能最大化發揮其效用的。 如果一個系統中有共性的類不多,無法/沒必要進行抽象,那就不適合使用這一程式設計模型。因為類例項化需要大量運算和記憶體。此時,使用面向過程的語言更合適。面向過程語言中所有方法都是靜態

面向物件程式設計思想的魅力

        說說面向物件程式設計         在學習面向程式之前,我先學了C語言,也就是面向過程的程式設計。學完C後的第一個感覺只能編寫一些及其簡單的題目,什麼判斷大小,或者利用一些迴圈語句,用批量判斷大小。最起碼我那時還不懂C專家的程式設計思想,所以覺得自己什麼都

面向物件和麵向過程

面向過程:就是將要實現一個功能所需要的步驟一步一步的寫出來出來,要做到面面俱到、有條不絮。   例如:在JavaScript如果需要在頁面當中插入一個DOM元素。按照面向過程的設計方法就是: var div = document.createElement(“div”);

面向物件程式設計思想總結

什麼是面向物件程式設計?   就是把一類具有相同屬性和動作的實體抽象成為計算機裡面的類, 也就是物件的模板, 把屬性和方法封裝成一個類中. 處理業務的流程就是物件之間的資訊傳遞. 把程式中的所有東西當做物件來進行處理.  為什麼需要面向物件程式設計?      

js面向物件程式設計思想

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <body> </bo

二十、面向物件----

1.面向物件與面向過程的區別 2.面向物件的基本特徵 2.1 封裝 2.2 繼承 2.3 多型

面向物件程式設計思想---OOP

在瞭解一些OOP知識後,覺得很有必要看看到底什麼是面向物件程式設計,這篇文章寫的很好,認真看下去收穫很大,所以就轉載了,感謝原創! 面向物件的方法論:  來自c++primer第十章 面向物件是一種程式設計的概念性方法,面向物件最重要的特徵是抽象、封裝和資料隱藏、多型、繼承、程式碼的可重用性。下面用一個例子來

php面向物件程式設計練習計算矩形、三角形、圓形的周長和麵積

剛剛學完php面向物件的程式設計,參考著高洛峰老師的php教程學習了這個例項。 效果圖片: 以下是實現程式碼: index.php <html> <hea

面向物件面向過程的區別

很多人剛入門時都不分不清這兩者的區別,我那時候也是。所以今天,就動筆寫了這篇文章,如有錯誤,歡迎指教! 我就不說那些定義了,就因為看不懂,所以才會來查文章,不是嘛?所以再複述也就沒有了意義! 首先,面向過程,就相當於一個人來做所有的過程。 而面向物件呢,就是把程式設計中的

C語言中的結構體與面向物件程式設計思想

沒有萬能的程式設計技術 沒有隻產生正確的結果的程式語言 不是每個專案的程式設計都是從零開始的 —-《Object-Oriented Programming With ANSI-C》 一、C語言結構體 1、結構體是什麼 (1