一個小白眼中的“面向對象”

《Head First Java》是我學習計算機以來第一本堅持讀下來的書,也是我見過的最有趣的編程語言教程。
不同於其他的書,這本書,或者說整個《Head First》系列,最大的不同之處,在於它們寫的根本不像教程,而像小說...讓讀者可以在愉快的氛圍中,不經意間就能明白很多課堂上老師怎麼“填鴨”也填不懂的概念。

本文是一個小白眼中的面向對象。

作爲某不知名院校的本科大學生,對於大學的計算機學習頗有感悟,
對於非計算機專業的學生來說,我們唯一一門計算機課就是《VC程序設計》,表面上是C++,實際就是C,因爲不涉及任何類和對象的知識,完全就是面向過程。學習的內容,僅僅是輸入輸出、數據類型、簡單的循環和判斷罷了...學習的效果呢,大多數學生記得最最最深刻的就是:

#include<iostream>
using namespace std;
int main(){
    return 0;
}

然後寫什麼來着...不知道了...
就是這個水平!
C++++.gif

所以,和許多大學生一樣,在學習Java之前根本不知道什麼是面向對象,腦子裏的思維也都是面向過程。

一、面向過程

首先,面向過程是什麼呢?
過程”,一想到這兩個詞,我大腦中的第一反應就是加工廠、生產流水線,也可以理解成數學中的函數。

“生產一杯咖啡需要怎麼做?”
需要水和咖啡粉作爲原料,先把水燒熱,然後倒入咖啡粉中就實現了。那麼我們可以畫這樣一張圖。
圖片.png

“過程”就是一個流水線,在面向過程設計程序的時候,我們只需要考慮,從輸入到輸出是怎樣實現的,經歷了怎樣的步驟,然後把這個實現方式拆分成一個一個的具體步驟,在程序運行時按順序去執行就可以了。於是面向過程就可以抽象成下圖:
圖片.png

面向過程中,所有的數據都是用變量來儲存的,所有的步驟都是通過函數來實現的。
在面向過程時,大腦裏面所想的都是流程,也就是工廠的每一道工序。

二、面向對象閃亮登場

那麼面向對象有什麼區別呢?

面向對象的思維,或許更接近與實際生活。
當我自己嘗試去理解對象時,我的大腦中呈現出的,不再是一個加工廠,而是一個生機盎然的公園,公園中有許多人和各種各樣的小動物,孩子們在嬉戲玩耍,蜜蜂在花叢中採蜜,旁邊還有一位作家坐在石凳上正準備打開電腦寫文稿...

這副畫面中,一個孩子、一隻蜜蜂、一朵花、一位作家、以及它手中的電腦,一切的一切,都是對象
而在這些對象之間,正在通過某種方法,發生着相互影響。
所以,面向對象和麪向過程最大的不同是,面向對象不再去關注完成某件事情需要怎樣的步驟,而是更加註重事物之間發生着怎樣的聯繫

對象包含兩個重要的內容:一個是對象的屬性、另一個則是對象的方法
以剛纔說到的作家手裏的筆記本來舉例:一臺筆記本,必然有一個狀態——開機或關機,那麼它的狀態就是一個屬性;筆記本還有內存大小、硬盤容量、CPU型號等等等,這些也都是這檯筆記本的屬性。

簡單來講:對象的“屬性”,就是在面向過程中提到的“變量”

“方法”又是什麼呢?現實生活中,一個方法其實就是要實現一個功能,比如筆記本的“開機”方法,就是把這檯筆記本的狀態從關閉變成打開,那麼“開機”就是這檯筆記本的一個方法;筆記本還可以打開文檔,並且顯示出文檔的內容,那麼“打印文檔信息”就是這檯筆記本的另一個方法,並且這個方法有輸出值,就是文檔信息的字符串。
那麼到底對象的“方法”要怎麼去解釋呢?——可以理解成面向過程中提到的“函數”。

圖片.png

但這並不嚴謹,或者說不完全正確,因爲變量只是爲了客觀儲存數據,而屬性雖然也可以儲存數據,但它是對象的一種特徵變量可以脫離對象而存在,但屬性不可以,如果沒有對象,屬性就失去了意義(如果沒有電腦這個實體,你能想象“開機”是一個什麼樣的狀態嗎?)。
同理,函數表示一種數據處理的過程,而方法表示此對象和其他對象發生聯繫的一種方式,方法也是不能脫離對象而存在的(如果讓一個從未見過電腦的人去關掉電腦,那也是很爲難他呢!)。

圖片.png

三、類

我們繼續拿筆記本電腦來舉例,小強、小達和小軒都有自己的筆記本電腦,而這些電腦都有共同的特點,所以就可以說,他們屬於同一個“類”。

“類”是什麼?
生活中的類是什麼呢?用通俗的語言說就是一羣有着共同特點的東西。所以類就是有着共同屬性和方法的一羣對象的模板、藍圖。如果幾個對象屬於同一個類,那麼這個類就含有這些對象共有的屬性和方法。並且,可以從這個類裏面再創建新的對象,新創建的對象同樣有這個類的特點。

或許初次接觸類和對象時,我們感受不到它有什麼用。我們繼續說,如果需要用變量來表示小強、小達和小軒三個人的電腦的信息,應該怎麼做呢?

假設,每一臺筆記本有三個信息:磁盤容量、內存大小、開關機狀態。

如果在面向過程的思維中,是這樣的:

//小強的筆記本
int XiaoQiang_Disk;
int XiaoQiang_Memory;
bool XiaoQiang_Status;

//小達的筆記本
int XiaoDa_Disk;
int XiaoDa_Memory;
bool XiaoDa_Status;

//小軒的筆記本
int XiaoXuan_Disk;
int XiaoXuan_Memory;
bool XiaoXurn_Status;

需要定義 3 * 3 = 9 個變量。

如果是面向對象呢?

//定義一個筆記本類
class laptop{
    int disk;
    int memory;
    bool status;
}

//基於這個類創建三個對象
laptop XiaoQiang = new laptop();
laptop XiaoDa = new laptop();
laptop XiaoXuan = new laptop();
    

需要定義 3 + 3 = 6 個變量。

或許這也不要緊,不就是少寫了幾個變量嘛?可是試想,如果需要表示的筆記本增加到10000個呢?
在面向過程的世界中,需要定義 10000 * 3 = 30000個變量;而使用面向對象的思維,只需要定義10000 + 3 = 10003個變量。

準確的講,如果通過某個類來新建一個對象,這個對象就會把這個類的所有非靜態屬性和非靜態方法複製一份,只要新建了這個對象,就相當於一次性把這個類的所有屬性都新建了一次。因此,面向對象有一個最簡單的好處,就是把本來需要新建指數個變量才能表示的信息,變成只需要新建線性級別的變量就能表示了。

四、繼承

面向對象的另一個好處就是繼承。
“繼承”這個詞用的十分形象,讓人可以瞬間想到生活中父母把自己的財物交給兒女,兒女接受財產的這個動作就是繼承,繼承也可以說是“下一代”從“上一代”的手中獲取了一些東西。“獲取”的究竟是什麼呢?——屬性和方法

被繼承的類叫做父類(給東西的類),執行繼承的類叫做子類(索取東西的類)。繼承這個動作可以理解成“以類爲模板,又新建了一個類”,從意義上說,子類是父類的具體化。

還是說計算機,計算機分爲很多種:PC機、筆記本、服務器...他們都是計算機,有許多共有特點,都有磁盤、內存、CPU...所以可以建立一個“計算機”類,表示所有計算機的模板。然而它們又有各自的特點,所有的筆記本都有電池,所有的服務器都有ECC校驗內存,所有的PC都有顯示器...所以,可以基於三者的特點分別建立這三個類,都從“計算機”類繼承,這樣他們既保留了公共屬性又有自己的特點。

圖片.png

五、多態和接口

還有更厲害的——那就是多態和接口...由於目前能力有限,因此留到下次再寫。

六、總結

在我這個小白看來,面向對象比面向過程更貼近實際生活,因爲一個對象可以是生活中的實物,所以只需要把這些物品的共有屬性抽象出來,就是一個類。面向對象的思維更容易去理解,也有許多優勢(繼承、接口、多態...)。

去年,在我初學計算機時,上來就被“面向過程”和“面向對象”這兩個詞給搞懵了,老師講課時的解釋模棱兩可,導致我根本不明白老師在說什麼,後來查了一些帖子,發現他們說的也不是很清楚...直到現在學習了PHP和Java,真正的做過了項目,纔對這兩個詞語有了較深的理解。對於上述概念如果有表達錯誤或者不準去的地方,歡迎指出。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章