“為什麼面向對象的編程會在軟件開發領域造成如此震憾的影響?”
面向對象編程(OOP)具有多方面的吸引力。對管理人員,它實現了更快和更廉價的開發與維護過程。對分析與設計人員,建模處理變得更加簡單,能生成清晰、易於維護的設計方案。對程序員,對象模型顯得如此高雅和淺顯。此外,面向對象工具以及庫的巨大威力使編程成為一項更使人愉悅的任務。每個人都可從中獲益,至少表面如此。
如果說它有缺點,那就是掌握它需付出的代價。思考對象的時候,需要采用形象思維,而不是程序化的思維。與程序化設計相比,對象的設計過程更具挑戰性??特別是在嘗試創建可重復使用(可再生)的對象時。過去,那些初涉面向對象編程領域的人都必須進行一項令人痛苦的選擇:
(1) 選擇一種諸如Smalltalk的語言,“出師”前必須掌握一個巨型的庫。
(2) 選擇幾乎根本沒有庫的C++(注釋①),然後深入學習這種語言,直至能自行編寫對象庫。
①:幸運的是,這一情況已有明顯改觀。現在有第三方庫以及標准的C++庫供選用。
事實上,很難很好地設計出對象??從而很難設計好任何東西。因此,只有數量相當少的“專家”能設計出最好的對象,然後讓其他人享用。對於成功的OOP語言,它們不僅集成了這種語言的語法以及一個編譯程序(編譯器),而且還有一個成功的開發環境,其中包含設計優良、易於使用的庫。所以,大多數程序員的首要任務就是用現有的對象解決自己的應用問題。本章的目標就是向大家揭示出面向對象編程的概念,並證明它有多麼簡單。
本章將向大家解釋Java的多項設計思想,並從概念上解釋面向對象的程序設計。但要注意在閱讀完本章後,並不能立即編寫出全功能的Java程序。所有詳細的說明和示例會在本書的其他章節慢慢道來。
1.1 抽象的進步
所有編程語言的最終目的都是提供一種“抽象”方法。一種較有爭議的說法是:解決問題的復雜程度直接取決於抽象的種類及質量。這兒的“種類”是指准備對什麼進行“抽象”?匯編語言是對基礎機器的少量抽象。後來的許多“命令式”語言(如FORTRAN,BASIC和C)是對匯編語言的一種抽象。與匯編語言相比,這些語言已有了長足的進步,但它們的抽象原理依然要求我們著重考慮計算機的結構,而非考慮問題本身的結構。在機器模型(位於“方案空間”)與實際解決的問題模型(位於“問題空間”)之間,程序員必須建立起一種聯系。這個過程要求人們付出較大的精力,而且由於它脫離了編程語言本身的范圍,造成程序代碼很難編寫,而且要花較大的代價進行維護。由此造成的副作用便是一門完善的“編程方法”學科。
為機器建模的另一個方法是為要解決的問題制作模型。對一些早期語言來說,如LISP和APL,它們的做法是“從不同的角度觀察世界”??“所有問題都歸納為列表”或“所有問題都歸納為算法”。PROLOG則將所有問題都歸納為決策鏈。對於這些語言,我們認為它們一部分是面向基於“強制”的編程,另一部分則是專為處理圖形符號設計的。每種方法都有自己特殊的用途,適合解決某一類的問題。但只要超出了它們力所能及的范圍,就會顯得非常笨拙。
面向對象的程序設計在此基礎上則跨出了一大步,程序員可利用一些工具表達問題空間內的元素。由於這種表達非常普遍,所以不必受限於特定類型的問題。我們將問題空間中的元素以及它們在方案空間的表示物稱作“對象”(Object)。當然,還有一些在問題空間沒有對應體的其他對象。通過添加新的對象類型,程序可進行靈活的調整,以便與特定的問題配合。所以在閱讀方案的描述代碼時,會讀到對問題進行表達的話語。與我們以前見過的相比,這無疑是一種更加靈活、更加強大的語言抽象方法。總之,OOP允許我們根據問題來描述問題,而不是根據方案。然而,仍有一個聯系途徑回到計算機。每個對象都類似一台小計算機;它們有自己的狀態,而且可要求它們進行特定的操作。與現實世界的“對象”或者“物體”相比,編程“對象”與它們也存在共通的地方:它們都有自己的特征和行為。