編程新手如何理解「面向對象」

先說一點,其實我是不建議新手去「深刻」理解面向對象的。所謂「深刻」,大概就以「設計模式」爲界吧。一般狀況下,兩年工做經驗如下的新人,去研究「設計模式」要麼是半途而廢(這算是好的),要麼就是把本身搞廢了(走火入魔)。php

這些年,談「設計模式」的人確實是愈來愈少了,並且前兩天我看到一個問題:面向對象(OOP)是編程語言發展中的彎路嗎?爲何?程序員

這個有點狠,呵呵。「彎路」倒談不上,只能說如今「面向對象」已經被拉下神壇,迴歸常態:再也不是「萬物皆對象」的狂熱,而應該是在適合面向對象的地方面向對象編程

不知道你們是否贊成:設計模式本質上是對傳統面向對象「弊端」的一種修補?這個說得深了一點,新手隨便看看就行。設計模式

說正事,編程新手應該如何理解「面向對象」?編程語言

首先,面向對象仍然是目前最主流、最有效地處理複雜業務邏輯的手段。你們不要矯枉過正,聽有些傢伙叫囂「面向對象已死」啥的。那麼多之前不支持面向對象的語言(好比php/JavaScript)都在盡力的往對象上面靠,就是一個明證。固然,學習面向對象,最好仍是經過純粹的、原生支持面向對象的語言,好比C#和Java,強烈建議經過JavaScript學習面向對象——太殘太擰太傷心……函數

其次,你們要明白「面向對象」要解決的問題,或者它使用的場景。面向對象並不適用於你在學習各類語言語法時寫的那些Demo程序(好比「冒泡排序」「圖書/課程管理系統」啥的),甚至於大多數的小型開發項目(好比普通的企業網站、我的博客)都不適合。面向對象適合的是那些業務邏輯複雜(其實用「繁雜」更恰當一些)的大型項目。所謂繁雜,繁指多,雜指亂,項目「雜亂」,能夠表現爲:功能多改動多,因此代碼量大、開發人員多、開發/維護跨度時間長……學習

這個我接下來還要繼續講,但你們先必定要有這個意識。否則你總是用「面向對象」套你那幾個小項目,怎麼抽象怎麼封裝,確定會越整越暈。小項目裏,「面向對象」沒用,體現不出來「面向對象」的那些好處——這也仍是爲何我一開始就講「不建議新手去‘深刻’理解面向對象」的緣由,這個階段,你接觸的項目規模有限,對代碼複雜性的理解有限,很難體會「面向對象」的做用。網站

最後,我給你們勾勒出理解面向對象的幾個層次,由淺入深,你們能夠依次理解。spa

一、學會面向對象的語法。類的聲明和繼承、接口和抽象類、方法和屬性、訪問修飾符……這個沒啥說的,很是簡單,都應該掌握。翻譯

二、想明白爲何會出現「類」。我推薦如何通俗易懂地舉例說明「面向對象」和「面向過程」有什麼區別?裏匿名用戶的高贊回答,簡單的說,函數太多,要分「類」管理。這就夠了,而後在實際開發工做中,試着把類分好,清晰有條理就能夠了。

三、明白「對象」是方法(函數)和數據的組合。由於若是你只停留在第2點的理解上,全部的類其實就是靜態類,全部的方法都是靜態方法。但類的一大特色,就是它自身是包含數據的,並且不一樣的數據能夠造就不一樣的實例(對象)。你看,直到這個時候,咱們才能說面向對象,而不是面向類。

四、開始「繼承」。注意,從這裏開始,就可能有陷阱了。繼承實際上帶來了兩個結果:重用和多態。重用很是好理解,子類可以使用父類全部非私有的屬性和方法嘛,因此不少同窗一使用繼承,就奔着「重用」去了。好比狗有四條腿,貓也有四條腿,那就抽象出一個有四條腿的父類:動物……但這樣作的問題是:桌子也有四條腿,咋整?因爲事物之間複雜的共性/特性關係,很容易就整出多重繼承出來,好比你開始是這樣構想的:

一切都很是美好,可是,接下來「鴨子」怎麼辦?你以爲它應該是禽類,可是請注意,它也是會游泳的(代碼裏須要這個功能)。同理,還有公雞,它也能夠產肉,又該怎麼辦?還有漂亮的畫眉,就是用來觀賞的,咋整?動物愈來愈多,這個體系就崩潰了……

因此這裏實際上是能夠批評「面向對象」的第一個點,或者層面。可是,永遠不要由於一門技術有這樣那樣的問題,就輕易的放棄。隨着你學習的深刻,你能夠有更深層次的理解。

五、用組合實現重用,用繼承實現多態。這其實是對第4條的一次「修補」(注意:不是「顛覆」)。我我的認爲,這實際上是「設計模式」的基礎或者核心。對於初學者而言,理解到這裏就差很少了;要講起來,也很是很是的難了。這幾乎上升到一種「藝術」的範疇了,好吧,飛哥認可,我本身對此的理解——理解多是理解了,但應用起來仍是捉襟見肘,不是很溜。就像你知道了不少公式,同樣解不出一道數學題同樣。

問題在哪裏?我稱之爲「複雜度守恆」。有的同窗或者據說過「‘面向對象’的設計可以下降複雜度」……但實際上,並無。業務邏輯的複雜度永遠是不可能下降的,除非你改需求;需求就是那樣了,因此複雜度就在哪裏了,你怎麼下降?不管是面向對象,仍是設計模式,和不面向對象編程(好比結構化編程)相比,其本質是把複雜度轉移到類的關係複雜度上。

我感受我好像又說得深了一點?就再說一點就停,可能有同窗知道工廠模式,可以幹掉醜陋的switch...case...,可是,switch...case...這種邏輯,真的消失了嗎?沒有啊!同窗,它不過是經過類的繼承和多態實現了呀。你以爲if...else...嵌套很是複雜,但數不清的類的關係同樣複雜啊!

我說這些,若是你是新人,可能根本體會不到。可能if...else...嵌套的複雜都還體會不到,就不用說其餘了。因此,就此打住吧。我以爲新人可以掌握第3個層次,理解到第4個層次,摸到第5個層次的邊,就很是很是不錯了。

 

可能有些同窗看了4和5,會以爲:那「面向對象」就確實沒有價值啊!就算是作到了第5個層次,也不過是「轉移」了複雜度而已。既然if...else...的嵌套和子類父類同樣複雜,我幹嗎要選擇子類父類這種複雜呢?

Good question!

我能給你最簡單的回答,兩個緣由:

一、「人腦」的侷限。面對復瑣事物,人腦的天然處理方式就是「抽象」和「屏蔽細節」。

假設你如今是一個元帥,要指揮一場戰役,你怎麼指揮?是否是隻會下達一個簡單的命令:第十四軍必須在15日之前佔領23號高地?至於十四軍如何佔領這個高地,兵力怎麼部署、火力怎麼配置、須要什麼樣的後勤資源……一堆的細節問題,你是否是隻能忽略掉?

二、從「代碼寫給電腦看」到「代碼是給人看」的轉變。

在計算機發展的初期,程序很是的簡單,電腦也沒法理解高級的複雜的——實際上就是「類天然語言」的指令,程序員大量的工做是把需求「翻譯」成電腦可以理解和執行的低級指令,好比石器時代的二進制打孔、彙編和C語言等等,形象的說就是「手把手」的教電腦如何操做,能夠具體到「分配32個字節的內存」「存儲到CPU的寄存器」這種粒度。

這種方式原始低效,根本沒法知足日益增加的軟件開發需求,一個最有效對接解決方式就是:把翻譯(編譯)的工做交給電腦本身去作,給程序員騰出時間和精力解決業務邏輯需求。因此,編程語言變得愈來愈「高級」愈來愈相似於人類天然語言。

其實,結構化編程的if...else...已經很接近人類語言了,但這還不夠。因而,「面向對象」應運而生。語言是思惟的載體:結構化語言,對應的仍然是具體的、一步一步執行性的思惟;面向對象,對應的是抽象的、以目標爲導向不論細節的的思惟!

仍然以戰役指揮爲例,面向過程,大概就是:

  1. 32門火炮轟擊地方陣地5分鐘
  2. 16名士兵配合2輛坦克向前衝鋒
  3. 1架直升機提供空中支援
  4. ……

面向對象就是:

第二連佔領地方陣地。

怎麼佔領?第二連本身去實現!

因而不少初學者就接受不了,內心是懸着的,他總是要去想:第二連到底是怎麼佔領這個陣地的呢?最關鍵的是,這個實現過程最後仍是得他本身去寫,因此他本能的就抗拒,或者說迷糊:進行面向對象的封裝啊抽象啊啥的,脫了褲子放屁,畫蛇添足嘛!O(∩_∩)O~

 

一不當心又寫了這麼多。可是呢,效果怎麼樣,我內心也是懸着的。因此,回到以前說的,我仍是不建議初學者深究「面向對象」,之後,有了工做經驗有了團隊分工合做接觸了大型項目,天然而然地就會逐漸明白:「面向對象」是被逼出來,而不是設計出來的!這一點,其實很是重要。

 

最後,給你們兩種圖:

尚未軟裝,等着加海報/壁畫等……

牀墊薄了,等着,海綿/棕墊正在路上

 

++++++++++++++++++++

 

飛哥的「一塊兒幫·源棧」全棧培訓,小班教學,拎包入住。

開業酬賓,折上再打折,有興趣的同窗加QQ羣:729600626,等着你來撩,^_^

相關文章
相關標籤/搜索