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

2021-10-14 02:10:47 字數 2803 閱讀 7695

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

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

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

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

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

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

// 物件是類這個抽象概念的例項,擁有獨自的資料

zhangsan = new tony(name=「zhangsan」, years=7, experience=「great」, tools=「high level」)

// 張三使用剪髮方法,為我們進行理髮

zhangsan.haircut()

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

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

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

做了這麼多年的技術,你有寫過部落格嗎?

最近使用cacti在公司搭建了一套監控系統,由於網上幾乎所有關於cacti的文章都停滯在幾年的0.8版本,就連官網的教程都是老版本的,因為老版本問題比較多,還可能存有注入漏洞,所以我採取了整體編譯安裝 奈何網上很少有人編譯cacti的,為此我還買了一本書,奈何沒有寫 最終花了3天時間。從頭到尾,編譯...

C 學了這麼多年,你仍不知道的事!!!

宣告是將乙個名稱引入程式。定義提供了乙個實體在程式中的唯一描述。宣告和定義有時是同時存在的。如inta externintb 1 只有當extern 中不存在初始化式是才是宣告。其他情況既是定義也是宣告。但是在下列情況下,宣告僅僅是宣告 1 僅僅提供函式原型。如 voidfunc int,int 2...

C 學了這麼多年,你仍不知道的事!!!

宣告是將乙個名稱引入程式。定義提供了乙個實體在程式中的唯一描述。宣告和定義有時是同時存在的。如inta externintb 1 只有當extern 中不存在初始化式是才是宣告。其他情況既是定義也是宣告。但是在下列情況下,宣告僅僅是宣告 1 僅僅提供函式原型。如 voidfunc int,int 2...