# 17 Lua 面向對象
Lua中的table就是一種對象,看以下一段簡單的代碼:
```lua
local tb1 = {a = 1, b = 2}
local tb2 = {a = 1, b = 2}
local tb3 = tb1
if tb1 == tb2 then
print ("tb1 == tb2")
else
print ("tb1 ~= tb2")
end
tb3.a = 3
print (tb1.a)
```
上述代碼會輸出tb1 ~= tb2。說明兩個具有相同值得對象是兩個不同的對象,同時在Lua中table是引用類型的。我們是基于table來實現的模塊,在table中可以定義函數,也就是說,每個table對象都可以擁有其自己的操作。看一段代碼:
```lua
Account = {balance = 0}
function Account.withDraw(v)
Account.balance = Account.balance - v
end
Account.withDraw(10) --調用函數
print(Account.balance)
```
上面的代碼創建了一個新函數,并將該函數存入Account對象的withDraw字段中,然后我們就可以調用該函數了。不過,在函數中使用全局名稱Account是一個不好的編程習慣,因為這個函數只能針對特定對象工作,并且,這個特定對象還必須存儲在特定的全局變量中。如果改變了對象的名稱,withDraw就再也不能工作了。例如以下代碼:
```lua
Account = {balance = 0}
function Account.withDraw(v)
Account.balance = Account.balance - v
end
Account.withDraw(10) --調用函數
print(Account.balance)
a = Account
Account = nil
a.withDraw(100)
```
```lua
-10
lua: test14_class.lua:23: attempt to index a nil value (global 'Account')
stack traceback:
test14_class.lua:23: in field 'withDraw'
test14_class.lua:32: in main chunk
[C]: in ?
```
這樣就會出現錯誤。我在這里使用Account創建了一個新的對象a,當將Account賦值為nil時,應該要對a對象不產生任何影響。但是,由于在函數withDraw內部使用了Account,而不是變量a,所以就出現了錯誤。如果我們將withDraw函數內部的Account.balance = Account.balance – v語句修改為:a.balance = a.balance – v,這樣就不會出現錯誤了。這就表明,當我們需要對一個函數進行操作時,需要指定實際的操作對象,即這里的a,這就需要一個額外的參數來表示該操作者,就好比C++中的this一樣,只不過這里將這個關鍵字換成了self,換完以后的代碼如下:
```lua
Account = {balance = 0}
function Account.withDraw(self, v)
self.balance = self.balance - v
end
a = Account
Account = nil
a.withDraw(a, 100)
print (a.balance)
```
這樣再調用,就不會出現錯誤了。
使用self參數是所有面向對象語言的一個核心。大多數面向對象語言都對程序員隱藏了self參數,從而使得程序員不必顯示地聲明這個參數。Lua也可以,當我們在定義函數時,使用了冒號,則能隱藏該參數,那么上述代碼使用冒號來改下,就是下面這個樣子了。
```lua
Account = {balance = 0}
function Account:withDraw(v) --注意這里寫的是":"
self.balance = self.balance-v
end
a = Account
Account = nil
a:withDraw(100) --注意這里調用時,也需要使用":"
print(a.balance)
```
冒號的作用很簡單,就是在方法定義中添加一個額外的隱藏參數,以及在一個方法調用中添加一個額外的實參。冒號只是一種語法便利,并沒有引入任何新的東西;如果你愿意,你可以可以不使用self,而是在每次定義一個函數時,手動的加上self,只要你處理好了self,它們都是一樣的。
這里亂亂的講了一些Lua中的東西,主要還是說了table是一個不一樣的東西,還有self。接下來,就正式進入面向對象的世界。不要忘了,上面總結的東西是非常有用的。
- 1 Lua介紹及環境
- 2 基本語法
- 3 數據類型
- 4 Lua 變量
- 5 循環
- 6 流程控制
- 7 函數
- 8 運算符
- 9 字符串
- 10 數組
- 11 迭代器
- 12 table
- 13 Lua 模塊與包
- 14 Lua 元表(Metatable)
- 14.1 元表案例
- 15 Lua 協同程序(coroutine)
- 16 Lua 文件IO
- 17 Lua 面向對象
- 17.1 類
- 17.2 繼承
- 17.3 封裝
- 18 Lua 與 Mysql
- 19 Lua 與 redis
- 20 Lua 與 JSON
- 21 Lua 與 http
- 22 Lua 與 Nginx
- 22.1 Nginx_Lua的安裝及環境
- 22.2 ngx_lua API(全表)
- 22.3 常用命令介紹
- 22 Lua 人工智能
- (1) Torch的安裝
- (2)Tensor
- Lua與C混合編程