物件導向編程

**物件導向編程**（，個簡稱可作）係程式編寫範式一種。如果話一位軟件工程師用 OOP 嚟寫程式，即係話佢以物件嚟做個程式嘅基本單元：一件物件會包括一柞特定嘅數據，呢啲數據（特性）因為用途上有某啲共通點而俾設計者擺埋一齊嚟睇；除此之外，一件物件通常仲會掕住一啲專門處理同嗰件物件相關嘅工作嘅子程序，呢啲子程序就係嗰件物件嘅方法。

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

喺廿一世紀初，有好多重要嘅應用－包括遊戲編程同人工智能呀噉－都成日會用到 OOP。因為 OOP 用途咁廣泛，有啲程式語言甚至仲係專門設計到支援 OOP 嘅，包括咗廿一世紀初常用嘅 C++、C♯、Java、Python 同 MATLAB 呀噉－呢啲程式語言就係所謂嘅**物件導向程式語言**。
## 基本諗頭

### 物件同類別

OOP 係一種程式編寫範式，根基概念係類別同物件。喺最基本嘅 OOP 當中，個程式裏面啲物件多數都係有返啲範本嚟參照造出嘅，呢啲範本就係所謂嘅類別－一個類別會講明屬於呢個類別嘅物件每一件會掕住嘅
*變數（特性）、同埋
*子程序（方法），
而一件物件就係佢所屬嗰個類別嘅一個實例，即係按個類別嘅模嚟造出嘅。用以下嘅 MATLAB 碼做例子：

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

### 達致抽象化

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

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

## 主要概念

OOP 有齊嗮基本編程會用嘅功能，例如係變數、數據結構同埋子程序呀噉。除咗呢啲基本功能之外，行 OOP 嘅程式語言仲成日會有以下呢啲功能：
### 生命週期

物件生命週期係指一件物件由**創造**至**剷走**之間嘅嗰段時間。當一個程式創建一件物件嗰陣，部電腦內部會搵個記憶體位置嚟裝住件物件嘅數據－「數據」包括件物件內部啲變數呀噉，而呢個時間點就係件物件嘅生命週期嘅起始點；喺個程式行嘅期間，個程式叫親部電腦用件物件，部機都會由件物件屬嘅記憶體位置攞數據用；而件物件相應嗰啲數據通常會喺以下呢啲情況下被剷走：
*喺廿一世紀初，通常當個程式行完嗰陣，部機就會唔再俾個程式霸住嗰啲記憶體位置，會俾第啲程式去用嗰啲記憶體（`release`），噉通常表示用有新嘅數據冚咗舊嗰啲佢；
*件物件屬嘅類別可能會有解構子嘅方法，或者類似功能嘅子程序，解構子做嘅係剷走一個類別嘅一個實例；
例如係以下呢段 C♯ 碼噉：

```csharp
class Complex { // 定義 Complex 呢個類別...
    ...  // 拉雜碼...
    // 定義個建構子...
    public Complex()
    {
        real = 0;
        img = 0;
    }
    ...  // 拉雜碼...
    ~Complex() // 定義 Complex 呢個類別嘅解構子，個解構子執行嗰陣會令電腦彈「Call zo destructor」嘅字眼出嚟（方便編程員睇）。
    {
        Console.WriteLine("Call zo destructor");
    }
}
```


### 封裝

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

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

```csharp
public class SaamLeonCe // 一個叫 Saam leon ce（三輪車）嘅 class...
{
    protected void Pedal() { } // Pedal()　呢個方法淨係可以由屬同一個 class、或者由呢個 class 延伸出嚟嘅 subclass 嘅碼使用。
    private int luk = 3; // luk 表示轆嘅數量，個特性係私有嘅，淨係可以由屬同一個 class 或者 struct 嘅碼使用。
    ...
}
```

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

### 繼承

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

舉個例說明，想像家陣有個遊戲程式，個程式要展示一個虛擬世界，個世界入面
*有 `Animal`（動物）呢個類別，呢個類別具有一柞特性－`data1`、`data2`，亦有柞特定嘅方法，例如係包含教個程式隻虛擬動物要點樣郁動嘅子程序 `move()`；
*又有若干件物件屬 `Dog`（狗）呢個子類別，呢個類別由 `Animal` 呢個超類別嗰度繼承咗 `move()` 呢個方法－即係話無論係虛擬狗定第啲虛擬動物，個程式都會用同一個子程序嚟計算隻動物要點樣郁動；
**多態：順帶一提，如果個程式入面 `Animal` 嘅唔同子類別各自嘅 `move()` 方法都唔同，噉個程式就展示咗電腦科學上講嘅多態－個超類別裏面有隻方法，隻方法有多個唔同嘅子類別都會用嘅，而且唔同子類別嘅呢隻方法都唔同樣；
*同時 `Dog` 又有 `bark()`（吠）呢個佢獨有嘅方法，呢個方法係淨係屬 `Dog` 嘅物件先至會用到嘅。
用繼承嘅做法會方便，因為個設計者唔使種種動物都同佢哋設一個類別同埋重新打過嗮啲好似 `move()` 噉種種動物都要用嘅碼。例如係好似以下呢段簡化嘅 C♯ 碼噉：

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

有啲程式語言（比較出名嘅有 C++ 同 Python）仲會支援多重繼承嘅功能，即係俾一個子類別有多過一個超類別，而嗰啲超類別之間冇直接嘅繼承關係。

### 物件組成

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

```python
class JyunGung:
    def __init__(self, id, name):
        self.id = id
        self.name = name
        self.deizi = None
```

上述段碼做嘅係定義 `JyunGung`（員工）呢個類別，個類別由幾個特性、方法同物件組成，當中 `deizi` 可以係一件物件，又會有 `gaaimeng`（街名）同 `city`（城市）等嘅組成部份。

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

```cpp
class GaauSau;  // 假設 GaauSau（教授）呢個類別喺個程式嘅第度定義咗，為咗慳篇幅呢度唔詳講。

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

  private: // 物件結合：GaauSau 組成（aggregate） BouMun 呢個類別。
    std::vector<std::weak_ptr<Professor>> members_;
    const std::string title_;
};
```

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

### 點造物件

基於類別定基於原型係兩種相對嘅 OOP 做法。基於類別編程意思係指個 OOP 程式以類別做出發點：

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

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

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

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

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

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

## 設計模式

物件導向設計指攞一個軟件設計上撞到嘅問題，諗計度出一個由物件組成嘅系統，用嚟解決個問題，不過仲未郁手寫源碼。舉個例說明，想像家陣有位遊戲製作師想要郁手開發一隻新嘅射擊遊戲，簡化噉講佢隻遊戲要呈現一個虛擬世界俾玩家睇，玩家要能夠喺個世界入面郁動同埋射擊虛擬嘅敵人；噉即係表示，隻遊戲嘅虛擬世界（一個程式）最低限度要有以下呢啲物件－
*玩家控制嘅角色－呢件物件要曉按玩家撳嘅掣決定點郁；
*若干個虛擬敵人－呢啲物件要曉郁、曉探測玩家角色嘅位置、曉生成虛擬子彈嚟攻擊玩家；
*若干嚿障礙物－呢啲物件每件都要有變數表示佢嘅位置，通常唔會點做其他嘢；
... 呀噉。喺郁手寫源碼打前，位遊戲製作師度好嗮「要有咩類別」、「要有咩物件」、「每個類別要有咩特性同方法」... 呢啲咁多問題嘅過程就係軟件設計，而好似上述個例子噉喺諗計階段經已打算用物件導向編程，就係所謂嘅物件導向設計。

### 常用模式

物件導向編程成日會配合以下呢啲設計模式：
*單例模式：指成個類別得一個實例，用家唔可以隨便建立新嘅實例；喺最簡單嗰種做法當中，個程式會有類似以下呢段 Java 碼入面嘅 `getInstance` 噉嘅程序，用嚟確保個實例唔會喺個程式入面出現多過一次：
*:
```java
public static synchronized Singleton getInstance() // synchronized 確保唔可以有兩段或者以上嘅過程同時行呢段碼；
    {
        if (obj==null) // 如果冇 instance...
            obj = new Singleton(); // 就整個新 instance
        return obj; // 將個新 instance 俾做 output
    }
```

**唔少軟件工程上嘅應用都興用單例模式，例如一個用 OOP 嘅程式入面啲工廠有好多時都會用單例模式，費事個程式有兩件工廠物件喺度各自建立物件，出現「有兩件物件 `[[識別碼|id]]` 一樣」等嘅撈絞情況。順帶一提，單例模式屬一種出名嘅建立型模式。
*工廠方法模式：又係種建立型模式，用工廠（喺 OOP 當中泛指曉建立第啲物件嘅物件）入面嘅方法嚟建立物件，而唔係吓吓都要想用件物件嘅物件親自（用自己嘅方法）建立；用 C++ 碼表達一件曉建立幾個類別嘅物件嘅工廠物件嘅話，段碼就會係好似以下噉：
*:
```cpp
using namespace std;
    enum VehicleType { // 列出 Vehicle 可以有邊幾種。
        VT_TwoWheeler,    VT_ThreeWheeler,    VT_FourWheeler
    };

    class Vehicle {
    public:
        virtual void printVehicle() = 0;
        static Vehicle* Create(VehicleType type);
    };
    // ... 每種 Vehicle 都有個類別。即係 class TwoWheeler : public Vehicle、class ThreeWheeler : public Vehicle 同埋 FourWheeler : public Vehicle。

    Vehicle* Vehicle::Create(VehicleType type) { // 呢個係工廠方法－按 input 決定要建立邊個類別嘅物件；如果想加新類別，設計者淨係要改呢度。
        if (type == VT_TwoWheeler)
            return new TwoWheeler();
        else if (type == VT_ThreeWheeler)
            return new ThreeWheeler();
        else if (type == VT_FourWheeler)
            return new FourWheeler();
        else return NULL;
    }
 
    class Client { // 有可能會想用 Vehicle 物件嘅類別
    public: 
    Client()
    {
        VehicleType type = VT_ThreeWheeler;
        pVehicle = Vehicle::Create(type); // Client 唔會親自建立物件，而係叫件工廠物件建立。
    }
    // 省略... 
};
// 下略...
```

**工廠方法模式有唔少好處，例如可以避免「一個子類別要有段同超類別唔一樣嘅碼，攞嚟建立子類別嘅物件」等嘅某啲撈絞情況。
*觀察者模式：行為型模式一種，指一件物件（`Subject`）內部留意住佢啲觀察者；每當某啲狀態出現變化嗰陣，`Subject` 都會通知自己啲觀察者，而且通常係透過叫觀察者嘅方法嚟通知；好似以下呢段 Java 碼噉：
*:
```java
// 省略開頭嗰啲 import...
    class EventSource {
        public interface Observer {
            void update(String event);
        }
    private final List<Observer> observers = new ArrayList<>(); // EventSource 有張 list 記住自己啲 observer...
  
    private void notifyObservers(String event) {
        observers.forEach(observer -> observer.update(event)); // 用 observer.update 嚟通知 observer 發生咗咩事。
    }  
    public void addObserver(Observer observer) {
        observers.add(observer);
    }  
    public void scanSystemIn() {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            notifyObservers(line);
        }
    }
}
```

**事件驅動編程成日都會用觀察者模式：事件驅動編程嘅做法係由「事件」嚟主導程式嘅流動，事件嘅例子有「踎士左掣撳咗」或者「鍵盤上邊個邊個掣俾人撳咗」等等，而一個事件驅動程式做嘅係要喺每件事件發生嗰陣俾相應嘅反應－例如一個射擊遊戲程式，每當玩家撳踎士左掣嗰時就要俾玩家角色開槍。
... 呀噉。

## 常用語言

因為 OOP 咁好使好用，有好多廿一世紀初常見嘅程式語言都支援 OOP（**物件導向程式語言**）。一般認為，Simula（1967 年）係史上第一隻用 OOP 嘅程式語言；除咗 Simula 之外，OOP 仲有好多語言可以用：
***純物件導向語言**：喺呢啲程式語言當中，程式裏面嘅所有嘢都被當係物件或者某啲物件嘅一部份，而且隻語言唔支援原始資料類型（即係唔俾用家設個獨立於物件嘅整數變數），例如 JavaScript 裏面可以有類似噉嘅碼－
*:
```javascript
int a = 5; 
  System.out.print(a);
```

**當中 `a` 係一個唔屬任何物件、單獨存在嘅整數型變數，而因為 JavaScript 容許呢樣嘢，所以 Javascript 就**唔**算係純物件導向語言。精確啲講，一隻程式語言要有齊嗮以下呢啲條件，先算純物件導向語言：
**#有齊封裝、繼承同多態嘅功能。
**#抽象化
**#事先定義咗嘅類型冚唪唥都係物件；
**#由用家定義嘅類型冚唪唥都係物件；
**#所有對啲物件做嘅運作都係通過啲物件用得嘅方法；
**喺廿一世紀初，比較出名嘅純物件導向語言包括咗 Ruby、Scala 同 Smalltalk 呀噉。
*有啲語言係主要預人做 OOP、但有少少程序式特徵嘅：例子有 Java、Python、C++ 同 C♯。
*又有啲語言係本來係程序式，但打後版本加入咗 OOP 功能嘅：例子有 PHP、Perl、MATLAB、COBOL、Fortran、Ada 同 Pascal。
*有啲語言有足夠嘅功能可支援 OOP，但有啲重要 OOP 功能佢哋係冇嘅，例如 JavaScript 就係噉。
... 等等。

## 相關概念

*可返用度：指一個程式入面啲部份（尤其係源碼）可以第時寫新程式嗰陣返用，喺軟件工程上係軟件嘅一樣理想特徵；有唔少電腦工作者都指出，OOP 其中一個最大嘅優點係啲程式可返用度高－例如喺電子遊戲製作上，遊戲製作師好容易可以攞自己程式入面啲類別去分享，第啲人想加類似物件落自己嘅電子遊戲嗰陣就可以慳返工夫。
*模塊化：簡化講就係指個程式嘅唔同部份有幾易「分拆開，每嚿都可以獨立運作」－高度模塊化表示個程式就算其中一橛軭咗，個程式嘅其餘部份都可以繼續運作；有唔少電腦工作者話 OOP 喺模塊化方面表現惡劣－例如淨係繼承嘅功能，就成日搞到啲程式出現「其中一段碼（例如類別）改咗，另外第啲碼（例如啲子類別）跟住就出問題」噉嘅情況。
*SOLID：指引「軟件工程應該點做」嘅一套原則，例如：
**里氏替換原則：SOLID 原則嘅其中一條；根據里氏替換原則，一位編程員用 OOP 寫程式嗰陣，應該要達到－
**:設 \phi(x) 做一個可以對屬類型 \text{T} 嘅物件 x 證明嘅特性；噉設 \text{S} 係 \text{T} 嘅子類型，如果 y 屬 \text{S}，噉 \phi(y) 應該要係真；
***用日常用語講，里氏替換原則意思係指「是但攞一件屬超類別嘅物件，件物件理應要有可能俾件屬子類別嘅物件取代，取代咗之後個程式起碼仲行到（未至於會輕機）」。喺廿一世紀初，里氏替換原則廣受採用，不過都唔係完全冇爭議性。
*遊戲編程：指電子遊戲嘅編程；廿一世紀初嘅遊戲編程成日都會用到 OOP，將遊戲嘅虛擬世界入面嘅嘢想像成一嚿嚿物件，事實係 Unity 等嘅遊戲引擎往往直頭假定咗隻遊戲嘅程式係用 OOP 嘅。
*動態分派
*DRY 原則
*關係數據庫
*個體為本模型
*剛體動力學
*廣義同狹義化

## 文獻
英文文獻：

*Armstrong, Deborah J. (February 2006). "The Quarks of Object-Oriented Development". *Communications of the ACM*. 49 (2): 123–128. doi:10.1145/1113034.1113040.
*Booch, G. (1997). *Object-Oriented Analysis and Design with Applications*. Addison-Wesley. ISBN 978-0-8053-5340-2.
*Harmon, Paul; William Morrissey (1996). *The Object Technology Casebook - Lessons from Award-Winning Business Applications*. John Wiley & Sons. ISBN 978-0-471-14717-6.
*Jacobson, I. (1992). *Object-Oriented Software Engineering: A Use Case-Driven Approach*. Addison-Wesley.
*Meyer, B. (1997). *Object-Oriented Software Construction*. Prentice Hall. ISBN 978-0-13-629155-8.
*Taylor, David A. (1992). *Object-Oriented Information Systems - Planning and Implementation*. John Wiley & Sons. ISBN 978-0-471-54364-0.
*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.

## 註釋

## 詞彙
外語詞彙：

## 引咗
引用來源：

## 拎

* Java 入便嘅 OOP 概念，GeeksforGeeks
* 軟件設計規律，GeeksforGeeks
* OOP 入門簡介，仲有更多料
* OOP 係一場昂貴嘅災禍，一定要消失
* 討論 OOP 嘅缺憾