物件導向編程

出自維基百科,自由嘅百科全書
(由物件導向跳轉過嚟)
跳去導覽 跳去搵嘢
Car 呢件物件喺個程式入面用嚟表示一架虛擬嘅「車」,會有若干隻特性同埋方法。

物件導向編程粵拼mat6 gin2 dou6 hoeng3 pin1 cing4英文object-oriented programmingOOP)係程式編寫範式一種。如果話一位軟件工程師用 OOP 嚟程式,即係話佢以物件(object)嚟做個程式嘅基本單元:一件物件會包括一柞特定嘅數據,呢啲數據(特性)因為用途上有某啲共通點而俾設計者擺埋一齊嚟睇;除此之外,一件物件通常仲會掕住一啲專門處理同嗰件物件相關嘅工作嘅子程序,呢啲子程序就係嗰件物件嘅方法[1][2]

舉個例說明,想像有隻電子遊戲程式,當中有兩件數據 fuel燃料嘅量)同埋 maxspeed(最大速率),兩件數據都係描述緊一架嘅特性(用途上有共通點),所以設計者就教個程式將兩件數據擺埋一齊做一件物件噉睇;而且件物件仲掕住咗柞方法,例如 refuel() 呢個子程序就係用嚟補充燃料(即係將 fuel 變返做佢嘅最大可能數值)嘅。部電腦內部會記住「呢幾個特性同方法屬同一件物件」,並且喺用家介面嗰度將佢哋擺埋一齊展示,等用家做起程式編寫上嚟易搞好多[3]

喺廿一世紀初,有好多重要嘅應用-包括遊戲編程[4]人工智能[5]呀噉-都成日會用到 OOP。因為 OOP 嘅廣泛用途,有啲程式語言甚至仲係專門設計到支援 OOP 嘅,包括咗廿一世紀初常用嘅 C++C♯JavaJavaScriptPythonMATLAB 呀噉-呢啲程式語言就係所謂嘅物件導向程式語言[註 1]

基本諗頭[編輯]

3D 電腦圖像整嘅一幅城市圖像;如果用嘅係 OOP,設計者可以索性叫部電腦
整一個叫 building 嘅類別;
整若干嚿屬 building 嘅物件出嚟;
當中嚿嚿嘅形狀同位置都唔同。
睇埋:程式編寫範式

物件同類別[編輯]

內文:物件 (電腦科學)類別 (電腦科學)

OOP 係一種程式編寫範式,根基概念係類別(class)同物件(object)。喺最基本嘅 OOP 當中,個程式裏面啲物件多數都係有返啲範本嚟參照造出嘅,呢啲範本就係所謂嘅類別-一個類別會講明屬於呢個類別嘅物件每一件會掕住嘅

而一件物件就係佢所屬嗰個類別嘅一個實例(instance),即係按個類別嘅模嚟造出嘅[6]。用以下嘅 MATLAB 做例子[7][8]

classdef BasicClass % 定義 BasicClass 呢個 class...
   properties % 呢個 class 有以下呢啲特性...
      Value {mustBeNumeric} % Value 係唯一一個特性,一定要係一個數...
   end
   methods % 呢個 class 有以下呢啲方法...
      function r = roundOff(obj) % 每個 function 都係一個方法...
         r = round([obj.Value],2);
      end
      function r = multiplyBy(obj,n)
         r = [obj.Value] * n;
      end
   end
end

...

a = BasicClass; % 創造一件叫 a 嘅物件,件物件屬 BasicClass 呢個 class。
a.Value = pi/3; % a 嘅 Value 設做 pi/3(圓周率除 3)咁多。

OOP 嘅諗頭源自 1960 年代[9],到咗 1990 年代經已成為咗其中一種最重要嘅程式編寫範式。噉係因為事實表明喺好多應用上,類別同物件嘅做法都幫到手令個程式更加容易打理:舉例說明,想像有位遊戲製作師喺度編寫佢隻新遊戲程式,佢想創造一個虛擬世界玩家喺裏面郁動;佢想個虛擬世界設計成好似一個現實嘅城市噉,度緊個城市其中一條街要點設計,佢想條街有幾架泊咗喺度做佈景,佢可以設定一個「車」嘅類別,個類別每個實例都有「色水」同「位置」等嘅變數,然後叫個程式將「建構一個車嘅實例」呢樣嘢做三次-就唔使吓吓都重新打過「建構一個車嘅實例」嘅碼。有研究者指,依種程式寫法能夠令個程式嘅運作更加貼近現實世界嘅思維,而且彼此相關嘅資料同行為,都會歸一喺一件物件之內,會比較易管理[10][11]

物件同類別可以比喻成整餅;攞嚟造物件嘅類別就好似一個餅模可以造出好多同款唔同味嘅餅噉,個程式可以將嗰四件物體當成喺「顏色」呢個變數上唔同、但屬同一個類別嘅物件。

達致抽象化[編輯]

內文:抽象化 (電腦科學)

OOP 能夠達致抽象化(abstraction):抽象化廣義上係指「忽略一個概念裏面啲唔重要嘅細節,淨係將啲重要嘅部份俾用家睇」;舉個例說明,想像一位遊戲製作師想寫一個遊戲程式,佢想喺隻遊戲入面俾玩家靠撳掣嚟控制主角郁(呢樣係好多遊戲都會用到嘅功能),於是(簡化講)佢就下載咗個程式[註 3],個程式能夠做到攞「玩家撳咗嘅掣」做 input,並且俾出「令遊戲嘅主角郁」做 output,而跟住呢位遊戲製作師就唔理個程式係點運作嘅,當個程式係個黑盒噉攞嚟用,淨係在意個程式嘅 inputoutput 關係(重要嘅部份)達得到佢想要嘅效果-即係將個程式內部啲演算法忽略[12]

OOP 當中嘅「物件」概念都係做到好似抽象化噉嘅效果:用家有咗件物件就可以忽略「件物件係點運作嘅」呢條問題,淨係集中諗件物件嘅 input-output 關係,以及係呢件物件做到嘅 input-output 關係可以點樣幫佢達到佢想要嘅功能,幫用家慳返好多時間同精神[13]

主要概念[編輯]

睇埋:電腦程式編寫同埋模塊化編程

OOP 有齊嗮基本編程會用嘅功能,例如係變數數據結構同埋子程序呀噉。除咗呢啲基本功能之外,行 OOP 嘅程式語言仲成日會有以下呢啲功能[14][15]

生命週期[編輯]

內文:物件生命週期
睇埋:建構子同埋解構子

物件生命週期(object lifetime)係指一件物件由「被創造」至「被剷走」之間嘅嗰段時間。當一個程式創建一件物件嗰陣,部電腦內部會搵個記憶體位置嚟裝住件物件嘅數據-「數據」包括件物件內部啲變數呀噉,而呢個時間點就係件物件嘅生命週期嘅起始點;喺個程式嘅期間,個程式叫親部電腦用件物件,部機都會由件物件屬嘅記憶體位置攞數據用;而件物件相應嗰啲數據通常會喺以下呢啲情況下被剷走[16]

  • 喺廿一世紀初,通常當個程式行完嗰陣,部機就會唔再俾個程式霸住嗰啲記憶體位置,會俾第啲程式去用嗰啲記憶體(release),噉通常表示用有新嘅數據冚咗舊嗰啲佢;
  • 件物件屬嘅類別可能會有解構子(destructor)嘅方法(或者類似功能嘅子程序;睇埋物件剷除),解構子做嘅係剷走一個類別嘅一個實例[註 4][17]

例如係以下呢段 C♯ 碼噉[18]

class Complex { // 定義 Complex 呢個類別...
    ...  // 拉雜碼...
    // 定義個建構子...
    public Complex()
    {
        real = 0;
        img = 0;
    }
    ...  // 拉雜碼...
    ~Complex() // 定義 Complex 呢個類別嘅解構子,個解構子喺被執行嗰陣會令部電腦彈「Destructor was called」噉嘅字眼出嚟(方便編程員睇同用)。
    {
        Console.WriteLine("Destructor was called");
    }
}

封裝[編輯]

內文:封裝 (物件導向編程)
睇埋:超距作用 (電腦科學)

封裝(encapsulation)係 OOP 當中嘅一個概念,負責將(通常係將屬同一件物件嘅)數據同埋操縱呢啲數據嘅子程序「包埋一齊」,等呢啲數據同子程序難以俾外界干擾同亂咁用。想像一個類別唔容許外界嘅碼直接使用一件物件內部嘅數據,淨係俾佢哋透過啲方法嚟使用啲數據,用返上面虛擬車嘅例子即係例如唔俾任何外界嘅碼直接更改 fuel 嘅數值,而淨係俾佢哋用 refuel() 呢個方法嚟改變 fuel 嘅數值,噉呢個類別就算係做咗封裝[19]

例如係好似以下呢段 C♯ 碼噉,就表示緊一個封裝好嘅類別:

public class Tricycle // 一個叫 Tricycle(三輪車)嘅 class...
{
    protected void Pedal() { } // Pedal() 呢個方法淨係可以由屬同一個 class、或者由呢個 class 延伸出嚟嘅 subclass 嘅碼使用。
    private int wheels = 3; // wheels 呢個特性係私有(private)嘅,淨係可以由屬同一個 class 或者 struct 嘅碼使用。
    ...
}

封裝相關嘅功能喺 OOP 上有好多優點:封裝可以防止個程式嘅第啲部份修改個類別嘅數據,而喺做代碼重構(refactoring)嗰陣可以令出錯嘅機會減低(因為保證咗個類別以外永遠都唔會有碼嘗試直接改變個類別嘅內容);而且如果個程式係預咗俾一啲外行嘅用家使用嘅話,將啲特性變成 private 又可以將啲數值收埋唔顯示喺用家介面嗰度,某程度上令到個程式易用啲-用家唔使睇住咁多唔同嘅變數[20]

繼承[編輯]

繼承嘅圖解;子類別會自動噉得到超類別嘅特性。
內文:繼承 (電腦科學)超類別 (電腦科學)子類別 (電腦科學)、 同 多重繼承
睇埋:多態 (電腦科學)同埋可返用性

繼承(inheritance)係 OOP 上嘅一個功能。喺 OOP 當中,繼承係指物件嘅類別之間可以有嘅一種關係。抽象啲噉講,如果話物件類別 A 由類別 B 嗰度「繼承」啲嘢,意思係指類別 B(超類別;superclass / parent)有嘅特性,類別 A(子類別;subclass / child)冚唪唥有齊嗮,不過類別 A 可以有類別 B 冇嘅特性。噉做用意通常係因為類別 A 所表示嘅事物概念上係類別 B 所表示嘅事物嘅一種,而用繼承嘅做法可以令到寫程式嗰陣慳返好多時間精神[21]

舉個例說明,想像家陣有個遊戲程式,個程式要展示一個虛擬世界,個世界入面

  • Animal動物)呢個類別,呢個類別具有一柞特性-data1data2,亦有柞特定嘅方法,例如係包含教個程式隻虛擬動物要點樣郁動嘅子程序 move()
  • 又有若干件物件屬 Dog)呢個子類別,呢個類別由 Animal 呢個超類別嗰度繼承咗 move() 呢個方法-即係話無論係虛擬狗定第啲虛擬動物,個程式都會用同一個子程序嚟計算隻動物要點樣郁動),
  • 同時 Dog 又有 bark())呢個佢獨有嘅方法,呢個方法係淨係屬 Dog 嘅物件先至會用到嘅。

用繼承嘅做法會方便,因為個設計者唔使種種動物都同佢哋設一個類別同埋重新打過嗮啲好似 move() 噉種種動物都要用嘅碼[21][22]。例如係好似以下呢段簡化嘅 C♯ 碼噉:

class Dog : Animal { // 創造一個 class 叫 Dog,呢個 class 嘅 superclass 係 Animal。
    // Dog 要做嘅嘢...
    public Dog()
    {
        Console.WriteLine("Dog");
    }
}

有啲程式語言(比較出名嘅有 C++Python)仲會支援多重繼承(multiple inheritance)嘅功能,即係俾一個子類別有多過一個超類別,而嗰啲超類別之間冇直接嘅繼承關係[23]

物件組成[編輯]

內文:物件組成物件結合

喺 OOP 當中,物件組成(object composition)廣義上係泛指將啲物件或者資料類型砌埋一齊組成更加複雜嘅物件[24]。舉例說明,想像家陣有個人想編寫一個資訊系統程式,用嚟記住一間企業員工嘅個人資料,佢個程式可能會一段好似以下噉嘅 Python[25]

class Employee:
    def __init__(self, id, name):
        self.id = id
        self.name = name
        self.address = None

上述段碼做嘅係定義 Employee(員工)呢個類別,個類別由幾個特性、方法同物件組成,當中 address 可以係一件物件,又會有 street(街名)同 city(城市)等嘅組成部份[25]

喺再進階啲嘅應用當中仲有所謂嘅物件結合(object aggregation):物件結合意思係指件複雜物件 com 由多件物件組成,但 com 並唔「擁有」啲組成部份-當 com 俾人剷走嗰陣,如果用嘅係物件組成,組成 com 啲物件都會跟住被剷走,但喺物件結合之下,啲組成部份並唔隸屬於 com,就算 com 俾人剷走,啲組成部份仲可以繼續噉存在。事實係有好多行 OOP 嘅程式語言都有陳述式專門做物件結合[24],例如想像一間大學又想整資訊系統記住啲員工嘅個資,可能會寫好似以下噉嘅 C++ 碼:

class Professor;  // Professor(教授)呢個類別喺個程式嘅第度定義咗,為咗慳篇幅呢度唔詳講。

class Department { // 定義 Department(部門)呢個類別...
  public:
    Department(const std::string& title): title_(title) {}

  private: // 物件結合:Professor 組成(aggregate)Department 呢個類別。
    std::vector<std::weak_ptr<Professor>> members_;
    const std::string title_;
};

-就算一個部門執咗,大學可能仲會想留住班教授同佢哋啲個資,調佢哋去第個部門做嘢,所以特登將個程式寫到唔會有「一剷咗一個部門嘅資料,啲教授嘅個資就跟住剷埋」噉嘅情況。

點造物件[編輯]

內文:基於類別編程基於原型編程

基於類別(class-based)定基於原型(prototype-based)係兩種相對嘅 OOP 做法[26]基於類別編程意思係指個 OOP 程式以類別做出發點:

 定義類別 X 有邊啲特性同方法;
 建立物件 A,A 屬類別 X;
 建立物件 B,B 屬類別 X... 如此類推;

基於原型編程就唔同,唔會明確噉定義「個類別係乜」,而係會攞一嚿已有嘅物體做「原型」-

 攞一嚿物件 A;
 建立一件新嘅物件 B,並且指明 B 繼承嗮 A 啲特性同方法(A 係 B 嘅原型);
 跟住可以用同樣嘅方法建立更多嘅物件;

喺廿一世紀初,主流嘅 OOP 係跟基於類別嘅做法嘅,不過都有唔少編程工作者比較鍾意用基於原型嘅做法,例如有啲工作者指出,基於類別嘅做法通常都係會將個程式啲類別定死咗,唔俾部電腦喺行個程式期間郁個類別嘅內容,而相比之下,基於原型嘅做法本質上就會容許呢樣嘢,好似係[27]

 攞物件 A 做物件 B 嘅原型;
 改物件 B 嘅特性同方法;
 攞物件 B 做物件 C 嘅原型;

而呢樣嘢被指能夠達致一啲基於類別做唔到嘅功能[28]。至於用基於原型編程嘅程式語言,可以睇吓 JavaScript [26]

設計模式[編輯]

仲未郁手寫源碼,但位軟件工程師經已喺度畫圖度定橋:個程式要有以下若干個類別,當中
單車bike) 係
交通工具vehicle)嘅子類別
內文:物件導向設計
睇埋:電子遊戲設計

物件導向設計(object-oriented design)係指攞個軟件設計上撞到嘅問題,諗計度出一個由物件組成嘅系統用嚟解決個問題,不過仲未郁手寫源碼。舉個例說明,想像家陣有位遊戲製作師想要郁手開發一隻新嘅射擊遊戲,簡化噉講佢隻遊戲要呈現一個虛擬世界玩家睇,玩家要能夠喺個世界入面郁動同埋射擊虛擬嘅敵人;噉即係表示,隻遊戲嘅虛擬世界(一個程式)最低限度要有以下呢啲物件[29][30]

  • 玩家控制嘅角色-呢件物件要曉按玩家撳嘅掣決定點郁;
  • 若干個虛擬敵人-呢啲物件要曉郁、曉探測玩家角色嘅位置、曉生成虛擬子彈嚟攻擊玩家;
  • 若干嚿障礙物-呢啲物件每件都要有變數表示佢嘅位置,通常唔會點做其他嘢;

... 呀噉。喺郁手寫源碼打前,位遊戲製作師度好嗮「要有咩類別」、「要有咩物件」、「每個類別要有咩特性同方法」[31]... 呢啲咁多問題嘅過程就係軟件設計,而好似上述個例子噉喺諗計階段經已打算用物件導向編程,就係所謂嘅物件導向設計[32]

物件導向編程成日會配合以下呢啲設計模式嚟用[32]

建立型模式[編輯]

內文:建立型模式

結構型模式[編輯]

內文:結構型模式

行為型模式[編輯]

內文:行為型模式

語言[編輯]

因為 OOP 咁好使好用,有好多廿一世紀初常見嘅程式語言都支援 OOP,包括:

... 等等。

批評[編輯]

睇埋[編輯]

註釋[編輯]

  1. 就算唔用物件導向程式語言,都係可以寫到物件導向嘅程式嘅,只係無咁方便噉解。
  2. 技術性啲噉講,個類別有嗰啲變數就係所謂嘅類別變數,而是但搵個類別變數 X,個類別嘅每個實例都會有一個對應嘅實例變數 Instance.X
  3. 可以睇吓遊戲資產嘅概念。
  4. 好多廿一世紀初嘅程式語言會自動噉安排俾物件數據霸住咗嘅記憶體要幾時釋放返出嚟,唔使用家擔心解構子嘅嘢。

文獻[編輯]

  • Armstrong, Deborah J. (February 2006). "The Quarks of Object-Oriented Development". Communications of the ACM. 49 (2): 123–128. doi:10.1145/1113034.1113040.
  • Pecinovsky, Rudolf (2013). OOP – Learn Object Oriented Thinking & Programming. Bruckner Publishing. ISBN 978-80-904661-8-0.
  • Schach, Stephen (2006). Object-Oriented and Classical Software Engineering, 7th Edition. McGraw-Hill. ISBN 978-0-07-319126-3.
  • Weisfeld, Matt (2009). The Object-Oriented Thought Process, 3rd Edition. Addison-Wesley. ISBN 978-0-672-33016-2.
  • West, David (2004). Object Thinking (Developer Reference). Microsoft Press. ISBN 978-0735619654.

[編輯]

  1. Kindler, E.; Krivy, I. (2011). "Object-Oriented Simulation of systems with sophisticated control". International Journal of General Systems: 313-343.
  2. Oppel, Andy (2005). SQL Demystified. McGraw Hill. p. 7.
  3. Lewis, John; Loftus, William (2008). Java Software Solutions Foundations of Programming Design 6th ed. Pearson Education Inc. Section 1.6 "Object-Oriented Programming".
  4. Chen, W. K., & Cheng, Y. C. (2007). Teaching object-oriented programming laboratory with computer game programming. IEEE Transactions on Education, 50(3), 197-203.
  5. Wechsler, H., & Rine, D. (1988, January). Object oriented programming (OOP) and its relevance to designing intelligent software systems. In Proceedings 1988 International Conference on Computer Languages (pp. 242-243). IEEE Computer Society.
  6. Booch, Grady (1986). Software Engineering with Ada. Addison Wesley. p. 220.
  7. Kindler, E.; Krivy, I. (2011). "Object-Oriented Simulation of systems with sophisticated control". International Journal of General Systems: 313–343.
  8. Lewis, John; Loftus, William (2008). Java Software Solutions Foundations of Programming Design (6th ed). Pearson Education Inc. ISBN 978-0-321-53205-3., section 1.6 "Object-Oriented Programming".
  9. McCarthy, John; Abrahams, Paul W.; Edwards, Daniel J.; Hart, swapnil d.; Levin, Michael I. (1962). LISP 1.5 Programmer's Manual. MIT Press. p. 105. ISBN 978-0-262-13011-0. Object - a synonym for atomic symbol.
  10. Quick Tip: Intro to Object-Oriented Programming for Game Development.
  11. Jacobson, Ivar (1992). Object-Oriented Software Engineering: A Use Case-Driven Approach. Addison-Wesley.
  12. Colburn, Timothy; Shute, Gary (5 June 2007). "Abstraction in Computer Science". Minds and Machines. 17 (2): 169-184.
  13. Object Oriented Programming (OOPs) Concept in Java. GeeksforGeeks.
  14. John C. Mitchell (2003). Concepts in programming languages, Cambridge University Press. p. 278. Lists: Dynamic dispatch, abstraction, subtype polymorphism, and inheritance.
  15. Michael Lee Scott (2006). Programming language pragmatics, Edition 2, Morgan Kaufmann. p. 470.
  16. Object Lifetime and Storage Duration in C++. Linux Hint.
  17. Destructors in C++. GeeksForGeeks.
  18. Destructors in C#. GeeksForGeeks.
  19. Rogers, Wm. Paul (18 May 2001). "Encapsulation is not information hiding". JavaWorld.
  20. Scott, Michael Lee (2006). Programming language pragmatics (2 ed.). Morgan Kaufmann. p. 481. "Encapsulation mechanisms enable the programmer to group data and the subroutines that operate on them together in one place, and to hide irrelevant details from the users of an abstraction."
  21. 21.0 21.1 Johnson, Ralph (August 26, 1991). "Designing Reusable Classes" (PDF). www.cse.msu.edu.
  22. Jacobsen, Ivar; Magnus Christerson; Patrik Jonsson; Gunnar Overgaard (1992). Object Oriented Software Engineering. Addison-Wesley ACM Press. pp. 43-69.
  23. Cargill, T. A. (Winter 1991). "Controversy: The Case Against Multiple Inheritance in C++". Computing Systems. 4 (1): 69-82.
  24. 24.0 24.1 Yaiser, Michelle. "Object-oriented programming concepts: Composition and aggregation". Archived from the original on April 8, 2015. There is a closely related concept to composition called aggregation. In conversation the differences between composition and aggregation are often ignored.
  25. 25.0 25.1 Composition in Python. Real Python.
  26. 26.0 26.1 Crockford, Douglas. "Prototypal Inheritance in JavaScript". Retrieved 22 June 2021.
  27. Taivalsaari, Antero (1996). Section 1.1". Classes vs. Prototypes: Some Philosophical and Historical Observations. pp. 44-50.
  28. Dony, Chistophe; Malenfan, Jacques; Bardou, Daniel. "Section 1.2" (PDF). Classifying Prototype-based Programming Languages. p. 17.
  29. Nacke, L. E., Grimshaw, M. N., & Lindley, C. A. (2010). More than a feeling: Measurement of sonic user experience and psychophysiology in a first-person shooter game. Interacting with computers, 22(5), 336-343.
  30. Shafer, D. M. (2012). Causes of state hostility and enjoyment in player versus player and player versus environment video games (PDF). Journal of Communication, 62(4), 719-737.
  31. The Case For Game Design Patterns. Gamasutra.
  32. 32.0 32.1 Gamma, E., Helm, R., Johnson, R., Johnson, R. E., & Vlissides, J. (1995). Design patterns: elements of reusable object-oriented software. Pearson Deutschland GmbH.

[編輯]