在lua原生语法特性中是不具备面向对象设计的特性。因此,要想在lua上像其他高级语言一样使用面向对象的设计方法,就需要使用原生的元表(metatable)来模拟面向对象设计。
一、元表setmetatable
对指定 table 设置元表(metatable),如果元表(metatable)中存在__metatable键值,setmetatable会失败。
以下实例演示了如何对指定的表设置元表:
1 2 3
| mytable = {} mymetatable = {} setmetatable(mytable,mymetatable)
|
二、元表__index 元方法
这是 metatable 最常用的键。
当你通过键来访问 table 的时候,如果这个键没有值,那么Lua就会寻找该table的metatable(假定有metatable)中的_index 键。如果_index包含一个表格,Lua会在表格中查找相应的键。
1 2 3 4 5 6
| other = { foo = 3 } t = setmetatable({}, { __index = other }) print(t.foo) 3 print(t.bar) nil
|
三、使用metatable实现继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| local _M = { version = 'lua 1.0' }
local parent = { __index = _M }
function parent.new() local new = {} setmetatable(new, parent) return new end
function _M:echo() print("M:echo "..self.version) end
|
四、使用metatable实现重载和多态
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| local _M = { version = 'lua 1.0' }
local parent = { __index = _M }
function parent.new() local new = {} setmetatable(new, parent) return new end
function _M:echo() print("M:echo "..self.version) end
local _M2 = parent.new()
local child = { __index = _M2 }
function child.new() local new = {} setmetatable(new, child) return new end
function _M2:echo() print("M2:echo "..self.version) end
test = parent.new() test:echo()
test = child.new() test:echo()
|