1. 程式人生 > 其它 >提了這麼多年的面向物件,你真的懂它的含義嗎?

提了這麼多年的面向物件,你真的懂它的含義嗎?

技術標籤:程式設計基礎程式語言面試java

面向物件

喬布斯採訪

1994 年 Rolling Stone 對喬布斯的採訪,喬布斯解釋了什麼是面向物件程式設計。

Jeff Goodell:請你用盡量簡練的語言解釋一下,究竟什麼是面向物件的軟體?

**喬布斯:**物件就像人一樣,也是活生生的生命。他們有知識,知道怎麼完成任務;他們有記憶,可以把發生的事情記下來。而你和他們的互動並不是低層次的,你是與他們在一個高度抽象的層面上互動,就像我們現在的對話一樣。

我舉個例子來說明。如果我是一個“洗衣”物件,你可以把髒衣服給我,然後告訴我說:“請幫我把這些衣服洗了吧!”而我恰好知道舊金山最好的洗衣房在哪,並且我會說英語,兜裡也有美元。於是我出門打了一輛計程車,告訴司機帶我去位於舊金山的洗衣房。我到了那裡洗好衣服之後,又坐車回到這裡。我把洗好的衣服交還給你,說:“你的衣服已經洗好了。”

你並不知道我是怎麼做到的。你不知道哪裡有洗衣店,也可能只會說法語,或者是兜裡沒錢,連車都打不了。但是我知道怎麼完成這項任務,而你不需要知道任何細節。所有的這些複雜流程都隱藏在我的內部,而我們之間可以高度抽象地互動。這就是物件。他們把複雜過程封裝在內部,而對外呈現的介面是高層次的,抽象的。

什麼是面向過程?

那到底什麼是面向物件?首先我們得了解面向過程。

面向過程的程式設計方法,注重解決問題的每一個步驟,並實現對應功能

比如,我們要完成一天的任務清單,今天的任務包括理髮、打掃衛生、搬家。於是我們開始按照順序,對每個步驟進行實現。

首先要理髮,於是我需要:

1.準備理髮工具
2.學習理髮技能
3.進行理髮

搞定之後,再進行打掃衛生,於是繼續實現其功能:

1.準備清潔工具
2.制定打掃計劃
3.進行打掃

最後要搬家,我們繼續拆解,完成這項任務:

1.物品打包
2.準備車輛
3.搬運物品
4.開車
5.卸貨
6.搬運物品
7.拆包整理

好了,今天的任務清單實現了。那麼,我們的功能也就打包上線了。

這樣編寫好的程式碼,都線性的堆在一起,那下次如果再想理髮、打掃衛生、搬家,那之前的程式碼怎麼複用呢?

我們這時,想到了函式的封裝。於是分別將理髮、打掃衛生、搬家這三個功能進行封裝,便於我們再次複用,減少開發的成本。

1. tony(){ 準備理髮工具、學習理髮技能、進行理髮 }
2. clean(){ 準備清潔工具、制定打掃計劃、進行打掃 }
3. move(){ 物品打包、準備車輛、搬運物品、開車、卸貨、搬運物品、拆包整理 }

但是,為什麼不一開始就封裝呢?因為我們使用的是面向過程的程式設計思路,出發點是注重怎麼樣一步一步的解決這個問題。

於是問題解決完成,功能實現,大量的線性程式碼已經寫完後,再去想怎麼封裝優化。

此時就花費的時間較久,而且也註定了封裝和複用性不夠好。

什麼是面向物件?

其實面向過程是一種低層次的互動。為什麼這麼說?想想我們在現實生活中,理髮、打掃衛生、搬家,真的會這麼麻煩嗎?

理髮,我們會去找理髮師(託尼);然後打掃衛生,可以親力親為,但也可以直接找清潔公司;搬家,就直接找搬家公司。

於是,我們一天的任務執行,變成了:

1. 理髮師,找到理髮師張三,進行理髮
2. 清潔工,找到清潔工李四,進行衛生打掃
3. 搬家公司,找到搬家公司X,進行搬家工作

理髮師不僅可以幫你理髮,他精通各種理髮技能,可以修剪各種髮型。於是,之後所有專案中的理髮任務,都可以交給他來完成。而清潔公司、搬家公司也是一樣的。於是我們的程式碼,就可以非常好的進行復用。

這就是面向物件的程式設計方式,它是現實世界的數字化抽象,更符合認知習慣。

所以我們要完成一項功能,先使用"類-Class"對功能進行封裝。

比如我們的理髮師,可以寫成這樣:

// 類是對現實世界抽象概念的數字化,包含資料和對資料的操作
class Tony {name, years, experience, tools; wash(), haircut(), blew(), show();}

但,理髮師其實是一個高層次的抽象,它是一個職業,包含了一些基本的資料,如姓名、從業年限、經驗、理髮使用的工具集,還有對這些資料的一些操作,我們稱為功能。

比如使用理髮工具集可以進行洗wash()、剪haircut()、吹blew(),理髮師可以使用自己的從業年限、經驗為自己進行宣傳show()。

使用類,定義了理髮師這個職業的一些符合我們公認的規範。但我們在尋求理髮師的幫助時,不會直接向這個"職業"直接發起請求,因為它本身就是一個抽象,理髮師那麼多?你找的是哪一個?

我們要找的是某一個從業者,比如理髮師張三。而張三就是類“理髮師”的一個物件,也稱為一個例項。張三成為理髮師後,擁有自己的資料,姓名=“張三”,從業7年,經驗豐富,使用高階理髮工具,同時擁有理髮師都應該擁有的技能:洗、剪、吹、宣傳。

所以,我們找到張三這個物件,為我們進行服務。

// 物件是類這個抽象概念的例項,擁有獨自的資料
zhangsan = new Tony(name=“zhangsan”, years=7, experience=“great”, tools=“high level”)
// 張三使用剪髮方法,為我們進行理髮
zhangsan.haircut()

於是,打掃衛生、搬家,同樣可以定義打掃衛生類、搬家類。然後使用它們的具體物件:清潔員小李、搬家員小王,來為我們完成服務。

這種程式設計方式,很明顯很接近現實世界的互動方式,所以福布斯說,它是一種更高層次的互動。而使用面向物件實現的程式碼,更容易複用,因為我們在寫程式碼時,目的就是更好的封裝,高內聚低耦合。

當然,這兩種程式設計方式沒有優劣之分。如果是嵌入式、專項、小型程式的開發,使用面向過程無疑是最為方便的,因為考慮面向物件的封裝可能會浪費大量時間。而在大型專案中,可能會進行大量的複用,這時使用面向物件開發,會為之後節省更多的成本。

結束語

如果有幫助的,記得點贊、關注。在公眾號《數舟》中,可以免費獲取專欄《資料倉庫》配套的視訊課程、大資料叢集自動安裝指令碼,並獲取進群交流的途徑。

我所有的大資料技術內容也會優先發布到公眾號中。如果對某些大資料技術有興趣,但沒有充足的時間,在群裡提出,我為大家安排分享。

公眾號自取:

公眾號