所有編程語言的最終目的都是提供一種“抽象”方法。一種較有爭議的說法是:解決問題的復雜程度直接取決於抽象的種類及質量。這兒的“種類”是指准備對什麼進行“抽象”?匯編語言是對基礎機器的少量抽象。後來的許多“命令式”語言(如FORTRAN,BASIC和C)是對匯編語言的一種抽象。與匯編語言相比,這些語言已有了長足的進步,但它們的抽象原理依然要求我們著重考慮計算機的結構,而非考慮問題本身的結構。在機器模型(位於“方案空間”)與實際解決的問題模型(位於“問題空間”)之間,程序員必須建立起一種聯系。這個過程要求人們付出較大的精力,而且由於它脫離了編程語言本身的范圍,造成程序代碼很難編寫,而且要花較大的代價進行維護。由此造成的副作用便是一門完善的“編程方法”學科。
為機器建模的另一個方法是為要解決的問題制作模型。對一些早期語言來說,如LISP和APL,它們的做法是“從不同的角度觀察世界”——“所有問題都歸納為列表”或“所有問題都歸納為算法”。PROLOG則將所有問題都歸納為決策鏈。對於這些語言,我們認為它們一部分是面向基於“強制”的編程,另一部分則是專為處理圖形符號設計的。每種方法都有自己特殊的用途,適合解決某一類的問題。但只要超出了它們力所能及的范圍,就會顯得非常笨拙。
面向對象的程序設計在此基礎上則跨出了一大步,程序員可利用一些工具表達問題空間內的元素。由於這種表達非常普遍,所以不必受限於特定類型的問題。我們將問題空間中的元素以及它們在方案空間的表示物稱作“對象”(Object)。當然,還有一些在問題空間沒有對應體的其他對象。通過添加新的對象類型,程序可進行靈活的調整,以便與特定的問題配合。所以在閱讀方案的描述代碼時,會讀到對問題進行表達的話語。與我們以前見過的相比,這無疑是一種更加靈活、更加強大的語言抽象方法。總之,OOP允許我們根據問題來描述問題,而不是根據方案。然而,仍有一個聯系途徑回到計算機。每個對象都類似一台小計算機;它們有自己的狀態,而且可要求它們進行特定的操作。與現實世界的“對象”或者“物體”相比,編程“對象”與它們也存在共通的地方:它們都有自己的特征和行為。
Alan Kay總結了Smalltalk的五大基本特征。這是第一種成功的面向對象程序設計語言,也是Java的基礎語言。通過這些特征,我們可理解“純粹”的面向對象程序設計方法是什麼樣的:
(1) 所有東西都是對象。可將對象想象成一種新型變量;它保存著數據,但可要求它對自身進行操作。理論上講,可從要解決的問題身上提出所有概念性的組件,然後在程序中將其表達為一個對象。
(2) 程序是一大堆對象的組合;通過消息傳遞,各對象知道自己該做些什麼。為了向對象發出請求,需向那個對象“發送一條消息”。更具體地講,可將消息想象為一個調用請求,它調用的是從屬於目標對象的一個子例程或函數。
(3) 每個對象都有自己的存儲空間,可容納其他對象。或者說,通過封裝現有對象,可制作出新型對象。所以,盡管對象的概念非常簡單,但在程序中卻可達到任意高的復雜程度。
(4) 每個對象都有一種類型。根據語法,每個對象都是某個“類”的一個“實例”。其中,“類”(Class)是“類型”(Type)的同義詞。一個類最重要的特征就是“能將什麼消息發給它?”。
(5) 同一類所有對象都能接收相同的消息。這實際是別有含義的一種說法,大家不久便能理解。由於類型為“圓”(Circle)的一個對象也屬於類型為“形狀”(Shape)的一個對象,所以一個圓完全能接收形狀消息。這意味著可讓程序代碼統一指揮“形狀”,令其自動控制所有符合“形狀”描述的對象,其中自然包括“圓”。這一特性稱為對象的“可替換性”,是OOP最重要的概念之一。
一些語言設計者認為面向對象的程序設計本身並不足以方便解決所有形式的程序問題,提倡將不同的方法組合成“多形程序設計語言”(注釋②)。
②:參見Timothy Budd編著的《Multiparadigm Programming in Leda》,Addison-Wesley 1995年出版。