物件導向程式設計（，縮寫：）是種具有物件概念的程式設計典範，同時也是一種程式開發的抽象方針。它可能包含資料、特性、程式碼與方法。物件則指的是類別（class）的例項。它將物件作為程式的基本單元，將程式和資料封裝其中，以提高軟體的重用性、靈活性和擴充套件性，物件裡的程式可以訪問及經常修改物件相關連的資料。在物件導向程式程式設計裡，電腦程式會被設計成彼此相關的物件，section 16 ObjectOriented Programming。 面向物件程式設計可以看作一種在程式中包含各種獨立而又互相呼叫的物件的思想，這與傳統的思想剛好相反：傳統的程式設計主張將程式看作一系列函式的集合，或者直接就是一系列對電腦下達的指令。面向物件程式設計中的每一個物件都應該能夠接受資料、處理資料並將資料傳達給其它物件，因此它們都可以被看作一個小型的 機器，即物件。目前已經被證實的是，面向物件程式設計推廣了程式的靈活性和可維護性，並且在大型專案設計中廣為應用。此外，支持者聲稱面向物件程式設計要比以往的做法更加便於學習，因為它能夠讓人們更簡單地設計並維護程式，使得程式更加便於分析、設計、理解。反對者在某些領域對此予以否認。 當我們提到面向物件的時候，它不僅指一種程式設計方法。它更多意義上是一種程式開發方式。在這一方面，我們必須瞭解更多關於面向物件系統分析和麵向物件設計（Object Oriented Design，簡稱 OOD）方面的知識。許多流行的程式語言是物件導向的，它們的風格就是會透由物件來創出例項。 重要的物件導向程式語言包含 Common Lisp、Python、C、ObjectiveC、Smalltalk、Delphi、Java、Swift、C、Perl、Ruby、JavaScript 與 PHP 等。 特徵 物件導向程式程式設計的定義是使用「物件」來做設計，但並非所有的程式語言都直接支援「物件導向程式程式設計」相關技術與結構。對於 OOP 的準確定義及其本意存在著不少爭論。通常，OOP 被理解為一種將程式分解為封裝資料及相關操作的模組而進行的程式設計方式。有別於其它程式設計方式，OOP 中的與某資料型別相關的一系列操作都被有機地封裝到該資料型別當中，而非散放於其外，因而 OOP 中的資料型別不僅有著狀態，還有著相關的行為。 面向物件的構建要素由三個部分組成，例項、類和元資料，元資料會儲存構建所需要的一切資訊。從關係上看，類與例項為一對多關係，類和元資料為一對一關係，例項會指向類，類會指向元資料，這種關係最終構成了所有面向物件的基類 object。 OOP 理論，及與之同名的 OOP 實踐相結合創造出了新的一個程式設計架構；OOP 思想被廣泛認為是非常有用的，以致一套新的程式設計範型被創造了出來。（其它的程式設計範型例如函數語言程式設計或程序式程式設計專注於程式執行的過程，而邏輯程式設計專注於引發程式程式碼執行的斷言）。對面向模擬系統的語言（如：SIMULA 67）的研究及對高可靠性系統架構（如：高效能作業系統和 CPU 的架構）的研究最終導致了 OOP 的誕生。其中由 Deborah J Armstrong 進行的長達 40 年之久的計算機著作調查中，顯示出了一系列面向物件程式設計的基本理論。物件導向程式特徵被條列如下 Deborah J Armstrong The Quarks of ObjectOriented Development A survey of nearly 40 years of computing literature which identified a number of fundamental concepts found in the large majority of definitions of OOP in descending order of popularity Inheritance Object Class Encapsulation Method Message Passing Polymorphism and AbstractionJohn C Mitchell Concepts in programming languages Cambridge University Press 2003 ISBN 0521780985 p278 Lists Dynamic dispatch abstraction subtype polymorphism and inheritanceMichael Lee Scott Programming language pragmatics Edition 2 Morgan Kaufmann 2006 ISBN 0126339511 p 470 Lists encapsulation inheritance and dynamic dispatch section 181 What is ObjectOriented Programming Lists Dynamic dispatch encapsulation or multimethods multiple dispatch subtype polymorphism inheritance or delegation open recursion thisself 分享非物件導向程式前身語言 物件導向程式設計通常共享高階程式語言的低階功能。可用於建構一個程式的基本工具包括： 變數：能儲存一些內建型態的資訊如整數與字元，也有些是資料結構像是字串、串列與雜湊表等包含內建或複合的變數如指標。 程式：也稱為函式、方法或例程，是指輸入資料產生輸出結果，現代語言還包含結構化程式設計結構如程式迴圈與條件。 類與物件 支援面向物件程式語言通常利用繼承其他類達到程式碼重用和可擴充套件性的特性。而類有兩個主要的概念： 類（Class）：定義了一件事物的抽象特點。類的定義包含了資料的形式以及對資料的操作。 物件（Object）：是類的例項（Instance）。 其中類（Class）定義了一件事物的抽象特點。類的定義包含了資料的形式以及對資料的操作。舉例來說，犬 這個類會包含犬的一切基礎特徵，即所有 犬 都共有的特徵或行為，例如它的品種、毛皮顏色和吠叫的能力。類可以為程式提供模版和結構。一個類的方法和屬性被稱為 成員。 我們來看一段虛擬碼： 類犬 開始 公有成員 吠 毛色 私有成員 品種 結束 在這串程式碼中，我們聲明瞭一個類，這個類具有一些犬的基本特徵。關於公有成員和私有成員，請參見下面的繼承性的內容。 物件（Object）是類的例項。物件有時會對應到現實世界中的事物，舉例來說，一個圖形程式可能有圓形、矩形與畫面等物件，一個線上購物系統可能有購物車、顧客與產品等類別。。有時物件會表示更抽象的實體，比如一個被開啟的檔案或是一個提供美國慣用量測轉換的服務。每個物件就是一個特定類別的例項（例如，名稱是 李華 的物件可能是類別僱員的一個例項）。程式在面向物件程式設計當中被視為方法，變數被視為成員或屬性。例如，犬 這個類列舉犬的特點，從而使這個類定義了世界上所有的犬。而大黃這個物件則是一條具體的犬，它的屬性也是具體的。犬有毛色，而大黃的毛色是黃色的。因此，大黃就是犬這個類的一個例項。一個具體物件屬性的值被稱作它的 狀態。（系統給物件分配記憶體空間，而不會給類分配記憶體空間。這很好理解，類是抽象的，系統不可能給抽象的東西分配空間，而物件則是具體的。） 假設我們已經在上面定義了犬這個類，我們就可以用這個類來定義物件： 定義大黃是犬 大黃。毛色：黃 大黃。吠 我們無法讓犬這個類去吠，但是我們可以讓物件 大黃 去吠，正如狗可以吠，但沒有具體的狗就無法吠。 類和物件就好比是 實型 和 123，實型 是一種資料的型別，而 123 是一個真正的 實數（即物件）。所有的 實數 都具有 實型 所描訴的特徵，如 實數的大小，系統則分配記憶體給 實數 儲存具體的數值。 動態配置與訊息傳遞機制 定義上動態配置是指方法會隨著例項動態的改變。而訊息傳遞機制（Message Passing）是指一個物件透過接受訊息、處理訊息、傳出訊息或使用其他類別的方法來實作一定功能。如：大黃可以透過吠引起人的注意，從而導致一系列的事發生。 封裝性 具備封裝性（Encapsulation）的物件導向程式設計隱藏了某一方法的具體執行步驟，取而代之的是透過訊息傳遞機制傳送訊息給它。封裝是透過限制只有特定類別的物件可以存取這一特定類別的成員，而它們通常利用介面實作訊息的傳入傳出。舉個例子，介面能確保幼犬這一特徵只能被賦予犬這一類。通常來說，成員會依它們的存取許可權被分為 3 種：公有成員、私有成員以及保護成員。有些語言更進一步：Java 可以限制同一包內不同類別的存取；C 和 VBNET 保留了為類別的成員聚集準備的關鍵字：internal（C）和 Friend（VBNET）；Eiffel 語言則可以讓使用者指定哪個類別可以存取所有成員。 因此，舉例來說，犬 這個類有 吠 的方法，這一方法定義了犬具體該透過什麼方法吠。但是，大黃的朋友並不知道它到底是如何吠的。 從例項來看： 一個面向過程的程式會這樣寫： 定義大黃 大黃。定音 442 大黃。吸氣 大黃。吐氣 而當狗的吠叫被封裝到類中，任何人都可以簡單地使用： 定義大黃是犬 大黃。吠 繼承 繼承性（Inheritance）是指，在某種情況下，一個類會有 子類。子類比原本的類（稱為父類）要更加具體化。例如，犬 這個類可能會有它的子類 中華田園犬 和 牧羊犬。在這種情況下，大黃 可能就是中華田園犬的一個例項。子類會繼承父類的和行為，並且也可包含它們自己的。我們假設 犬 這個類有一個方法（行為）叫做 吠 和一個屬性叫做 毛色。它的子類（前例中的中華田園犬和牧羊犬）會繼承這些成員。這意味著程式設計師只需要將相同的程式碼寫一次。 在虛擬碼中我們可以這樣寫： 類 中華田園犬：繼承 犬 開始 中華田園犬繼承了犬類的所有方法 結束 建立物件 定義 大黃 是 中華田園犬 呼叫方法 大黃。吠 註釋：注意這裡呼叫的是犬類的吠 方法。 回到前面的例子，中華田園犬 這個類可以繼承 毛色 這個屬性，並指定其為黃色。而 牧羊犬 則可以繼承 吠 這個方法，並指定它的音調。子類也可以加入新的成員，例如，牧羊犬 這個類可以加入一個方法叫做 放牧 。設若用 中華田園犬 這個類定義了一個例項 大黃，那麼大黃就不會放牧，因為這個方法是屬於牧羊犬的，而非中華田園犬。事實上，我們可以把繼承理解為 是 或 屬於。大黃 是 中華田園犬，中華田園犬 屬於 犬類。因此，大黃既得到了中華田園犬的屬性，又繼承了犬的屬性。 我們來看虛擬碼： 類 牧羊犬：繼承 犬 開始 公有成員 放牧 結束 類 中華田園犬：繼承 犬 開始 中華田園犬類中沒有放牧 方法 結束 建立物件 定義 大黃 是 中華田園犬 呼叫方法 大黃。放牧 註釋：錯誤：放牧 是牧羊犬的成員方法，中華田園犬沒有這個方法。 當一個類從多個父類繼承時，我們稱之為 多重繼承。如一隻狗既是中華田園犬又是牧羊犬。多重繼承並不總是被支援的，因為它很難理解，又很難被好好使用。 多型 多型（Polymorphism）是指由繼承而產生的相關的不同的類，其物件對同一訊息會做出不同的響應譚浩強：《C 面向物件程式設計》，清華大學出版社，2006 年 1 月第一版。ISBN 9787302123156。例如，狗和雞都有 叫 這一方法，但是呼叫狗的 叫 ，狗會吠叫；呼叫雞的 叫 ，雞則會啼叫。 我們將它體現在虛擬碼上： 類 犬 開始 公有成員 叫 開始 吠 結束 結束 類 雞 開始 公有成員 叫 開始 啼 結束 結束 建立物件 定義 大黃 是 犬 定義 紅帽 是 雞 呼叫方法 大黃。叫 紅帽。叫 這樣，雖然同樣是做出叫這一種行為，但大黃和紅帽具體做出的表現方式將大不相同。多型性的概念可以用在運算子過載上，可以根據需求檢視相關介面。 抽象性 抽象（Abstraction）是簡化複雜的現實問題的途徑，它可以為具體問題找到最恰當的類定義，並且可以在最恰當的繼承級別解釋問題。舉例說明，大黃在大多數時候都被當作一條狗，但是如果想要讓它做中華田園犬做的事，你完全可以呼叫中華田園犬的方法。如果狗這個類還有動物的父類，那麼你完全可以視大黃為動物。 歷史 面向物件程式設計的雛形，早在 1960 年代的 Simula 語言中即可發現，當時的程式設計領域正面臨著一種危機：在軟硬體環境逐漸複雜的情況下，軟體如何得到良好的維護？面向物件程式設計在某種程度上透過強調可重複性解決了這一問題。20 世紀 70 年代的 Smalltalk 語言在面向物件方面堪稱經典 以至於 30 年後的今天依然將這一語言視為面嚮物件語言的基礎。 計算機科學中物件和例項概念的最早萌芽可以追溯到麻省理工學院的 PDP1 系統。這一系統大概是最早的基於容量架構（capability based architecture）的實際系統。另外 1963 年 Ivan Sutherland 的 Sketchpad 應用中也蘊含了同樣的思想。物件作為程式設計實體最早是於 1960 年代由 Simula 67 語言引入思維。Simula 這一語言是奧利 約翰達爾和克利斯登奈加特在奧斯陸的為模擬環境而設計的。（據說，他們是為了模擬船隻而設計的這種語言，並且對不同船隻間屬性的相互影響感興趣。他們將不同的船隻歸納為不同的類，而每一個物件，基於它的類，可以定義它自己的屬性和行為。）這種辦法是分析式程式的最早概念體現。在分析式程式中，我們將真實世界的物件對映到抽象的物件，這叫做 模擬。Simula 不僅引入了 類 的概念，還應用了例項這一思想 這可能是這些概念的最早應用。 20 世紀 70 年代施樂 PARC 研究所發明的 Smalltalk 語言將面向物件程式設計的概念定義為，在基礎運算中，對物件和訊息的廣泛應用。Smalltalk 的建立者深受 Simula 67 的主要思想影響，但 Smalltalk 中的物件是完全動態的 它們可以被建立、修改並銷燬，這與 Simula 中的靜態物件有所區別。此外，Smalltalk 還引入了繼承性的思想，它因此一舉超越了不可建立例項的程式設計模型和不具備繼承性的 Simula。此外，Simula 67 的思想亦被應用在許多不同的語言，如 Lisp、Pascal。 面向物件程式設計在 80 年代成為了一種主導思想，這主要應歸功於 CC 語言的擴充版。在圖形使用者介面（GUI）日漸崛起的情況下，面向物件程式設計很好地適應了潮流。GUI 和麵向物件程式設計的緊密關聯在 Mac OS X 中可見一斑。Mac OS X 是由 ObjectiveC 語言寫成的，這一語言是一個仿 Smalltalk 的 C 語言擴充版。面向物件程式設計的思想也使事件處理式的程式設計更加廣泛被應用（雖然這一概念並非僅存在於面向物件程式設計）。一種說法是，GUI 的引入極大地推動了面向物件程式設計的發展。 蘇黎世聯邦理工學院的尼克勞斯維爾特和他的同事們對抽象資料和模組化程式設計進行了研究。Modula2 將這些都包括了進去，而 Oberon 則包括了一種特殊的面向物件方法 不同於 Smalltalk 與 C。 面向物件的特性也被加入了當時較為流行的語言：Ada、BASIC、Lisp、Fortran、Pascal 以及種種。由於這些語言最初並沒有面向物件的設計，故而這種糅合常常會導致相容性和維護性的問題。與之相反的是，純正的 面嚮物件語言卻缺乏一些程式設計師們賴以生存的特性。在這一大環境下，開發新的語言成為了當務之急。作為先行者，Eiffel 成功地解決了這些問題，併成為了當時較受歡迎的語言。 在過去的幾年中，Java 語言成為了廣為應用的語言，除了它與 C 和 C 語法上的近似性。Java 的可移植性是它的成功中不可磨滅的一步，因為這一特性，已吸引了龐大的程式設計師群的投入。 在最近的計算機語言發展中，一些既支援面向物件程式設計，又支援面向過程程式設計的語言悄然浮出水面。它們中的佼佼者有 Python、Ruby 等等。 正如面向過程程式設計使得結構化程式設計的技術得以提升，現代的面向物件程式設計方法使得對設計模式的用途、契約式設計和建模語言（如 UML）技術也得到了一定提升。 物件導向程式語言 支援部分或絕大部分面向物件特性的語言即可稱為基於物件的或面向物件的語言。Simula 1967 被視為第一個具有物件導向特性的語言。早期，完全面向物件的語言主要包括 Smalltalk 等語言，目前較為流行的語言中有 Java、C、Eiffel 等。隨著軟體工業的發展，比較早的程式導向的語言在近些年的發展中也紛紛吸收了許多物件導向的概念，比如 CC，CObjectiveC，BASICVisual BasicVisual Basic NET，PascalObject Pascal，AdaAda95。「純粹」的物件導向語言，因為所有的東西都是由物件所組成，例如：Eiffel Emerald JADE Obix Ruby Scala Smalltalk Self 指令碼中的 OOP 近年來，面向物件的程式設計越來越流行於指令碼語言中。Python 和 Ruby 是建立在 OOP 原理的指令碼語言，Perl 和 PHP 亦分別在 Perl 5 和 PHP 4 時加入物件導向特性。 參見 一次且僅一次（once and only once，OAOO） Distributed Component Object Model UML 參考文獻 延伸閱讀 外部連結 Introduction to Object Oriented Programming Concepts OOP and More by LWC Nirosh Discussion about the flaws of OOD OOP Concepts Java Tutorials Category 程式設計典範 Category 軟體開發 Category 軟體工程