第一版是為 Lua 5.0 編寫的。儘管在很大程度上仍然適用於後續版本,但仍存在一些差異。
第四版針對 Lua 5.3,可在 Amazon 和其他書店購買。
購買本書,您還可以幫助 支持 Lua 項目。
![]() |
Lua 中的 編程 | ![]() |
第二部分。表格和物件 第 16 章。物件導向程式設計 |
Lua 中的表格在多種意義上都是物件。與物件一樣,表格具有狀態。與物件一樣,表格具有獨立於其值的識別(「自我性」);具體來說,具有相同值的兩個物件(表格)是不同的物件,而一個物件可以在不同的時間具有不同的值,但它始終是同一個物件。與物件一樣,表格具有獨立於誰創建它們或在哪裡創建它們的生命週期。
物件有自己的操作。表格也可以有操作
Account = {balance = 0} function Account.withdraw (v) Account.balance = Account.balance - v end此定義創建一個新函數並將其儲存在
Account
物件的 withdraw
欄位中。然後,我們可以這樣呼叫它
Account.withdraw(100.00)
這種函數幾乎就是我們所說的「方法」。但是,在函數內部使用全域名稱 Account
是一種不好的程式設計實務。首先,此函數僅對此特定物件有效。其次,即使對於此特定物件,該函數也僅在物件儲存在該特定全域變數中時才有效;如果我們更改此物件的名稱,withdraw
將不再起作用
a = Account; Account = nil a.withdraw(100.00) -- ERROR!這種行為違反了物件具有獨立生命週期的前述原則。
更靈活的方法是在運算的接收者上運算。為此,我們必須定義方法,並加上一個額外的參數,告訴方法它必須在哪些物件上運算。這個參數通常稱為self或this
function Account.withdraw (self, v) self.balance = self.balance - v end現在,當我們呼叫方法時,我們必須指定它必須在哪些物件上運算
a1 = Account; Account = nil ... a1.withdraw(a1, 100.00) -- OK透過使用self參數,我們可以使用相同的方法來處理許多物件
a2 = {balance=0, withdraw = Account.withdraw} ... a2.withdraw(a2, 260.00)
self參數的這種用法是任何物件導向語言的重點。大多數的物件導向語言都將此機制部分隱藏於程式設計師,因此程式設計師不必宣告此參數(儘管程式設計師仍可以在方法內使用名稱self或this)。Lua也可以隱藏此參數,使用冒號運算子。我們可以將前一個方法定義改寫成
function Account:withdraw (v) self.balance = self.balance - v end並將方法呼叫改寫成
a:withdraw(100.00)冒號的效果是在方法定義中新增一個額外的隱藏參數,並在方法呼叫中新增一個額外的引數。冒號只是一個語法上的便利設施,儘管它很方便;這裡並沒有什麼真正的新東西。我們可以使用點語法定義一個函式,並使用冒號語法呼叫它,反之亦然,只要我們正確處理額外的參數即可
Account = { balance=0, withdraw = function (self, v) self.balance = self.balance - v end } function Account:deposit (v) self.balance = self.balance + v end Account.deposit(Account, 200.00) Account:withdraw(100.00)
現在,我們的物件具有身分、狀態和對此狀態的運算。它們仍然缺乏類別系統、繼承和私密性。讓我們解決第一個問題:我們如何建立具有類似行為的幾個物件?具體來說,我們如何建立幾個帳戶?
版權所有 © 2003–2004 Roberto Ierusalimschy。保留所有權利。 | ![]() |