【Lua 筆記】物件導向程式設計(Object Oriented Programming,OOP) - part 11
【Lua 筆記】物件導向程式設計(Object Oriented Programming,OOP) - part 11
由於有款遊戲叫做 CSO(Counter-Strike Online),內建模式創世者模式(Studio)新增使用 Lua 及其遊戲的 API,所以突發奇想製作這個筆記。
這個筆記會在一開始先著重純粹的程式設計自學,在最後的章節才會與 CSO 遊戲 API 進行應用。
小提醒:此為本筆記最後一章,恭喜你可以準備結合CSO的API實作了。
物件導向程式設計(Object Oriented Programming,OOP)
物件導向程式設計(Object-Oriented Programming, OOP)是一種程式設計範式,強調使用「物件」來設計軟體和程式碼。物件是具有狀態(屬性)和行為(方法)的實體。OOP 的主要目的是提高程式碼的可重用性、可維護性和可擴展性。
舉個例子:比如我現在正在 coding,用物件導向程式設計的邏輯來看的話,就是如以下表格所示(參考自:何謂物件導向程式設計 - HackMD):
| 類別(class) | 物件名稱(name) | 物件屬性(property) | 物件操作方法(method) |
|---|---|---|---|
| 人類 | 我(LukeTseng) | 具有靈活的雙手 | 操作鍵盤滑鼠 |
| 電腦 | 個人電腦 PC | CPU:i5-6400、GPU:MSI RTX 4060 Ti 8G 等 | 控制各個元件 |
| 鍵盤 | Logic Signature K855 | 具有許多鍵位(如:WASD等) | 鍵盤輸入文字 |
| 螢幕 | MSI(我忘記是啥型號了XD) | 100 Hz、內建喇叭等 | 顯示彩色畫面、文字 |
物件,想像成是一個形體或物品,就好比我這個個體就是一種物件,電腦也是一種物件。但是細分下去,CPU、GPU等等也都可以被稱為是一種物件。
回歸到 Lua 本身,其實他並不是完全或原生的物件導向的程式語言,但是我們可以透過 table、metatable 模擬出物件導向的特性。
以下是關於物件導向的特性:
- 封裝(Encapsulation):將物件的狀態(屬性)和行為(方法)封裝在一起,並隱藏物件的內部實際細節。這樣可以保護物件的狀態不被外部直接修改,只能通過物件的方法來運算。
- 繼承(Inheritance):能讓一個類別(子類別)從另一個類別(父類別)繼承屬性和方法。這樣可以重複使用父類別的程式碼,並在子類別中擴展或修改其行為(方法)。
- 多型(Polymorphism):能讓不同的物件以相同的方式響應相同的方法呼叫。表示可以用相同的介面來操作不同型態的物件,且不需要知道它們的具體型態。(簡短說就是指同一行為能有不同結果,例如滑鼠左鍵點某個網站連結直接導向那個網站,在網站裡面點各個按鈕又是不一樣的結果)
- 抽象(Abstraction):指只顯示物件的必要部分,隱藏不必要的細節。可以簡化複雜系統的設計,讓 user 只需要用到重要的部分。
關於上述四點,筆者這邊用 python 的例子來舉例:
1 | # 封裝(Encapsulation) |
1 | # 繼承(Inheritance) |
1 | # 多型(Polymorphism) |
抽象的部分就不舉例了(因為抽象概念其實好了解,另外程式上也用到語法糖的語法,只顯示重要的部份給 user,簡化使用者介面的複雜程度)
接下來讓我們進入 Lua 版本的物件導向程式設計
Lua 物件導向
物件是由屬性和方法所組成的。Lua 中最基本的資料結構是 table,所以需要用 table 來描述物件的屬性。
方法其實就是由函數(function)所組成的,所以可以在 lua 當中用 table + function 重現 class。
以下是用表與函數結合的模擬類別(來自:Lua 面向对象 | 菜鸟教程):
1 | Account = {balance = 0} |
這個函數的作用域被保存在 Account 裡面做使用,也就是所謂的方法(Method),可以用以下這方式呼叫這個函數:
1 | Account.withdraw(100.00) |
是不是就有點像之前學過的字串方法呢?像是:string.upper() 一樣。
以下是筆者自創範例:
1 | -- 定義 Person 類別 |
:::info
建構方法(又稱構造函數:Constructor):主要用於在創建物件時「初始化」物件,給物件成員變數(屬性)賦予初始值。
local person1 = Person:new("John", 30) 創建一個物件(實例:Instance,一個具體的物件,有詳細的內容,在這範例當中包含人名跟年齡)。實例就直接看成一個個體,像筆者 LukeTseng 是一個個體,更詳細一點內容就是我的身高年齡血壓等等,每個實例的屬性值可以是不同的,表示每個實例都是獨立的,擁有自己的狀態。
print(person1.age) 存取 person1 實例的屬性。
:::
:::info
為什麼用冒號 :?
1 | -- 使用點(.)呼叫 |
用 . 需要明確輸入參數進去,用冒號的話,Lua 自動將 Person 作為 self 參數傳遞給showInfo 函數,使呼叫動作更加簡潔、直觀。
:::
Lua 繼承
可以透過 metatable 實現。
1 | -- 父類別 Animal 定義 |
總結
物件導向程式設計(Object-Oriented Programming, OOP)是一種強調使用「物件」來設計軟體和程式碼的程式設計範式。物件是具有狀態(屬性)和行為(方法)的實體。OOP 的主要目的是提高程式碼的可重用性、可維護性和可擴展性。
OOP 的四大特性包括:
- 封裝(Encapsulation):將物件的狀態和行為封裝在一起,隱藏內部細節,只能通過物件的方法來操作狀態。
- 繼承(Inheritance):允許一個類別(子類別)從另一個類別(父類別)繼承屬性和方法,實現程式碼的重用。
- 多型(Polymorphism):不同的物件可以以相同的方式響應相同的方法呼叫,實現同一行為有不同的執行結果。(簡單來說就是同一行為有不同結果)
- 抽象(Abstraction):隱藏不必要的細節,只顯示物件的必要部分,簡化系統設計。
Lua 雖然不是原生物件導向的語言,但可以透過 table 和 metatable 來模擬類別(class)、繼承(inheritance)等物件導向的特性。
Lua 用 table 來描述物件的屬性,並通過函數(function)來實現方法。透過 metatable 的機制,Lua 能夠模擬出類別的繼承。



