1. 程式人生 > >面向物件程式設計思想的魅力

面向物件程式設計思想的魅力

        說說面向物件程式設計         在學習面向程式之前,我先學了C語言,也就是面向過程的程式設計。學完C後的第一個感覺只能編寫一些及其簡單的題目,什麼判斷大小,或者利用一些迴圈語句,用批量判斷大小。最起碼我那時還不懂C專家的程式設計思想,所以覺得自己什麼都寫不出來。(當然要寫出一些有點技術含量的程式碼還需要非常多其他的知識)。那時候C語言的課程設計寫一個五子棋,一個把資料關係變相表達出來的一個程式,那時候用了兩個星期,結合網上的程式碼才勉強寫出來。在那時候,有關五子棋的每一個步驟都必須考慮的清清楚楚,何時應該重新整理棋盤等等,面向過程的程式設計模式讓人必須集中精神關注整個程式執行的狀態和有關數值的變化,在除錯和挖掘錯誤的時候讓人非常痛苦。 到了大二第一學期,我開始學習C++,正確來說,應該是通過C++去學習面向物件程式設計思想。這相對於面向過程的程式設計思想來說,這種新的設計思想更好的描述問題狀態,讓我們思考解決方案的時候更加舒服,是一種充滿魅力的設計思想。非常幸運在大二的時候遇到一位幽默的鄭建華老師,他風趣地向我們介紹了面向物件程式設計的方法和特點,最近在學習JAVA,在思考面向物件程式設計的時候經常會想起這位老師的話,在教師節之際也把此文獻給這位負責而幽默的老師。 在學習JAVA的時候,有一本非常好的書《JAVA程式設計思想》,英文《Thinking in Java》。看起來非常厚,儘管只是看了很少的一部分,但也受益匪淺。這篇博文非常多的思想和知識都源自於這本優秀的教材(除了自己胡扯的一部分)。 “純粹”的面向物件程式設計方法有以下幾點 1、所有的東西都是物件,存在其有關資料和方法。 這話說等於沒說,剛剛接觸程式設計的人覺得這一句話就是一句廢話,但是要真正思考這個問題我覺得還需要結合非常多的知識。 2、程式是物件的組合,並且通過傳送訊息來告知彼此需要做的。 3、每個物件都有自己的有其他物件所構成的儲存。4、每個物件都有自己的型別。 5、某一特定型別的所有物件都可以接收同樣的訊息。(多型的起點) 譬如說一個計算器程式,假如使用一個面向過程的思想來設計,第一步:輸入資料;第二步:分析資料;第三步:計算;第四部:輸出結果。然後按照這樣的思路再一步一步地在一個mian函式裡面表示出來。假如使用面向物件的思想來設計,有一個能計算的類(帶有mian入口),它有儲存數字的空間,它還包含一個運算機,能夠輸入和輸出的方法;運算機又有一個計算的部件(另外一個物件),有能進行四則運算的基本方法等等....這樣的程式設計慢慢細化,雖然最底層的方法還是通過描述過程去實現,但是新思想對於整個問題的分割是非常形象,編寫程式的時候讓我們更舒服。在後期的維護會更加容易,譬如說,要增加一個來平方的功能,在面向物件的設計思想中可以找準某一個模組或者方法,進行相關修改。 前一段時間,一位正學習java的朋友向我問起繼承ArrayList類的toString方法的過載,他要實現一個遍歷的過程,想嘗試直接在toString方法中直接遍歷。在很多人看來,就遍歷來說,這肯定不是一個好方法,而朋友卻死磕這個點,於是我也和他一起死磕,弄了好久才把它實現。後來我想朋友怎麼會那樣去死磕,除了相信自己的方法可行之外我覺得是他還沒了解面向物件程式設計的封裝原則。死磕是可以瞭解到程式語言中語法的使用,但盲目地死磕只會浪費時間,任何一門語言都有其設計的缺陷,很多時候死磕意義不大,我們要學習的是語言設計者的思想,遵循其中的潛在規則,這會讓我們更好地運用這門程式語言。 封裝是面向物件程式設計的三大特點之一。形式很簡單,就是把物件的資料和方法封裝起來,形成一個整體,通過public對外開放可運用的屬性和方法。我一直在想,為什麼要封裝?這個答案是一下子說不清楚的,編了一段時間的java後(純粹的面嚮物件語言),就發覺,封裝真的是一個好東西! 封裝的好處建立在優質類上。我所理解的優質類是功能分明獨立,介面靈活,過程安全。這一種類就應該好好地封裝起來,僅供運用,儘量少地去修改其內部功能。java的API就是java設計者已經做好的優秀的類,可以靈活地實現我們非常多的需求,而且功能相對獨立。我們需要充分信任封裝的類,那樣我們就可以更高效地去設計程式頂層上的演算法。就像我們用人一樣,充分相信他的能力,不過問他的工作情況,這樣的團隊會更加高效,而作為領隊的你可以集中精神去處理高階的業務。同時作為一個領隊,不應該過分干預隊員的工作,就像我和我的朋友去過載toString一樣,雖然事情最後辦好了,但是亂得像一鍋粥一樣。作為一個類的製作者之一,寫程式的時候一定要嚴謹,清楚程式的功能,運用優質的演算法,一步一步地設計,這樣的類可靠性才強。這樣我們在使用起來才能清楚瞭解到封裝的魅力。 封裝得完美,會延伸出另外一個問題。打個比喻,我的團隊裡的人都精通自己的領域,有時候我希望他們能再多懂一些新知識來滿足專案的需要,那樣我就不需要為一個新專案再多僱一個程式設計師了。我說的就是繼承,java的關鍵字也extends,意思是擴充套件,我們習慣稱作繼承。意思也差不多,繼承父類的功能並加以擴充套件。繼承的原則就是更加細節化,具體化,譬如:生物,動物,貓科動物,貓,波斯貓。。。上述就是一種典型的繼承關係,一步一步地擴充套件,子類的適用面會變小,但針對性更強,解決具體問題的能力也會更強。這也是繼承的原則,清楚繼承的來源,我們很快就會理解關於java裡面一些關於繼承的規定,譬如說繼承中父類方法和子類方法的呼叫等等。java中不能多繼承,改用介面去實現多繼承的功能,介面是繼承和多型的活用,我覺得是java和c++的區別之一,非常好用,有機會再詳細聊聊。 封裝完美,繼承使功能擴充套件,擴充套件完美,又會引出一個新問題。還是打一個比喻,我的團隊越做越大,好多的員工(假設繼承的類也算是新員工,畢竟是一個新類),中午我要叫他們吃飯,我肯定是大叫一聲“全體人員去吃飯”,然後我的員工都去吃飯了。我們程式化這個過程,我向所有的物件發出了同一條訊息(所有的物件來自不同的類,但來自同一個高階父類——人)。換句話說,我用的人引用去給所有的物件發出吃飯的命令,然後大家就去吃飯了。再從員工的角度分析,淑女程式媛聽到我的命令,她優雅地吃起飯來;飢餓的程式猿聽到我的命令,狂吃起來。各個不同的員工都有自己吃飯的方式,再抽象這個過程,就是不同的物件接收到一個相同的呼叫資訊,做出不同的反應。這不就是多型的定義了嗎?多型的功能很有用,封裝和繼承會讓類變得精美而繁多,多型也會去其糟粕,刪繁就簡,保留其中精華的同時還簡化了中間的關係。 封裝,繼承,多型是面向物件程式設計的三個特點,不難發現三個特點是相互支援的,我們可以按照上文的順序推匯出這三個特點,也可以從其他順序進行思考,同樣可以完美地得出這三個特點。每每想到這裡,都會感嘆設計出這種程式設計思想的大師是多麼的有智慧。圍繞著這三大特點,我們在學習java其他的功能和語法的時候都會容易得多,很容易就可以對這些功能進行解釋,很快就可以接受並且掌握。在具體程式設計的時候,圍繞這幾個特點作為原則,也會少走很多歪路,編出有條理的程式來。 寫程式是一件非常有趣的事,面向物件更加有趣,因為它直接描述,形象地解決問題。挖掘其中程式設計的思想,同樣能發現非常多有趣的思維。 這篇博文是最近思考面向物件思想的時候總結出來的,本人知道得甚少,難免會有錯漏。分享成果是希望可以共同進步,各位大神見到錯漏的地方請指出,同時希望幫到初學面向物件程式設計的師弟師妹們,有任何疑問都可以留言。