標籤:

書上說C++是面對對象語言,這是什麼意思?能舉個好懂的例子嗎

感覺大部分說的都太抽象,能舉個生活中的例子嗎?還有,C++是怎麼做到面對對象的?其他語言面對過程又是怎麼一回事


http://www.stroustrup.com/whatis.pdf

http://www.stroustrup.com/oopsla.pdf


面向對象是一種抽象的方式。

抽象指的是,將具體的事物往人的思維層次上靠,的過程。

例如,將一個棧,看成一個可以push和pop的存在。(數據抽象)

例如,將hash map,red-black tree,linked list,看成可以get(key), put(key, val)的字典(繼承)

抽象的目的是為了降低程序員的思維負擔,手指與頸椎損傷,以及未來可能出現的bug。

降低思維負擔,於是人能站在更高的層面思考問題,然後能設計更複雜的系統。

這種抽象方式,依靠的一定的語法結構,這些語法結構包括類,繼承,介面,etc。這些語法結構幫助程序員更好地組織代碼,實現代碼復用,管理資源和狀態,etc。

當然了,沒有這些語法結構你也可以抽象,用C語言嘛,只不過寫起來啰嗦了點。

面向對象的例子多了去了,比如常見的「食物-水果-香蕉」啦,「交通工具-帶輪子的-自行車」,自行車還有個成員函數,叫做「ride()」啦,這些例子就是逗你玩兒的,想真正理解面向對象,只能靠多寫代碼多看書多思考。


(嘗試用通俗語言解釋了一下,畢竟很多教科書在說明OOP的時候,用的很多生詞本身就讓初學者看不懂。但要能通俗的解釋一遍,又簡單,又完全不出差錯,的確有點困難;我也只能盡量了,有什麼問題歡迎指正)

面向對象英文叫Object-Oriented,我一直覺得這個中文翻譯得不好,感覺像萬年找不到對象的屌絲程序員,在擼片子時候饑渴難耐無意翻譯出來的東西。。。

Object-Oriented Programming (OOP)我一直理解為面向物體編程(這個翻譯當然也不好,減少點歧義而已),就是程序內部不是一個個子程序,而是一個個的物體塊,快裡面定義了各種各樣的功能。過去的面向過程編程就是一個一個子程序,這也是最傳統的編程方式。但問題是如果子程序之間有關聯的話(比如新子程序大部分功能來自於某箇舊子程序,只是為了不同情況做很小的改動之類),那麼你只能把子程序copy and paste一下,然後在新代碼里加入改動。如果代碼量比較少的話還好,多起來的話就是一種浪費了,而且可維護性極差(想想看如果那箇舊程序被挑出來一個bug,那麼就要一個一個的找那些paste後的新子程序對應點的內容,如果是十幾個這樣的部分,那絕對是一場噩夢。。。)。

OOP就是解決上面這個問題而發明得,用正常的中文來說,就是將程序看做是完成一個一個功能,而非一個一個子程序。這些功能,相近的那些組合成一個個Object,然後再在Object裡面加入諸如屬性啊之類的東西。這些所謂的功能,和往常的子程序的區別,就是當我寫了一個功能之後,只要定義得好,他是可以用於不同的情況得;而子程序就算功能相同,在不同的情況下也要寫不同的copy,也就是我上面一段說的問題。比如說C++的template,他的一個功能,就是當輸入得format (int, char之類)不一致時,我依舊能夠用同一段代碼來實現,而非為了不同的format case寫幾個幾乎完全一模一樣的代碼。。。

那麼為什麼要以OOP的形式解決這個復用的問題,其實是為了解決面向過程的另一個難實現的功能:舉個例子,如果我要設計一個遊戲,遊戲里有很多怪,每過段時間就刷出來個新得。如果是OOP的話,我可以先定義一個類,這個類說明了這個怪的各種特點,他如何襲擊人,血量多少,受傷後會做什麼動作,等等等等。這樣刷出來一個新怪,在程序實現中就是按照這個類新建一個object,那麼這個怪的object就能自動擁有獨立的屬性和功能,而怪與怪之間的狀態也能互相隔開,我搞死某個怪也就是刪除掉那個怪的Object,絕對符合人類正常的直覺。這對面向過程編程來說,其靈活性和實現的簡易性,是完全難以想像的。這也是為什麼,遊戲編程領域是C++的傳統地盤的原因,既能高效率運算,又符合OOP,而且還功能強大,嗯。。。


主要是思考方式,從南京到北京,怎麼走?

面向過程語言:首先買票,然後去火車站,發車時間到了就檢票,上車,然後過了一定的時間,就到了。

面向對象語言:有個東西叫火車票,它的功能是讓你坐上火車;有個東西叫火車,它的功能是把將你在兩個地方傳送。當你有了火車票和火車,在適當的時機發揮它們的功能,就能從南京到北京了。


Object-Oriented 被翻譯成面向對象真是悲哀,誤導了無數剛接觸C++或者Java的新手。看看對岸的翻譯「物件導向」,才更符合其中心思想。


補充一下吧。

按照吉格斯的例子(手機不會@,找不到。。。。)。突然這個人不想去北京,要去海南了。

面向過程:你需要買一張飛機票,然後你要去機場,機場的位置和火車站不一樣,得用演算法2走。買了機票然後檢票,和火車不一樣,沒有站台。登機後去海南。

面向對象:有個新東西叫飛機票,和火車票一樣。有個新東西叫飛機,和火車一樣是交通工具。有了飛機票和飛機,你就可以到海南了。

到了海南又想去台灣了。

面向過程:你需要買一張船票,然後你要去碼頭,碼頭的位置又變了,你需要用演算法3去。買了船票在碼頭等船來,坐船去台灣。

面向對象:有個新東西叫船票,和火車票飛機票一樣,都是票。有個新東西叫船,和火車飛機一樣,都是交通工具。有了船票和船,你就台灣了到了。

實際使用中,不斷改變的需求就是不斷改變的目的地,用了面向對象的思想,編譯起來更簡單,因為你的程序就是一個票和一個交通工具(這就是結構體和類)。這就是所謂的好維護。

當然,程序肯定是有過程和演算法的,只是面向過程的情況下,每次需求(目的地)改變了,都要重寫一次演算法,太麻煩。

如果能保證產品經理的需求一錘定音,永不改變,那當然面向過程編程更簡單。

慢慢體會吧。同是新人表示共勉。


推薦閱讀:

我看一些ACM訓練人員的代碼風格的一些總結,這對以後的職業發展好嗎?
如果要改進C語言,您最希望添加哪些語言特性,移除哪些語言特性?
以C++為核心語言的高頻交易系統是如何做到低延遲的?
每次編程開始先輸入 #include,那麼計算機在讀取 # 符號的時候 正在做什麼?
Android 會像 Windows 一樣,打敗 iOS 嗎?

TAG:CC |