lua类与对象

来源:互联网 发布:照相机内存卡数据恢复 编辑:程序博客网 时间:2024/06/08 05:37
lua中是可以进行面向对象编程的,可通过元表和元方法来实现。
按照我个人的理解,对一个表定义了元表之后,可修改这个表的一些特定行为。比如,对一个表定义了元表,而在元表里实现了__add的元方法,就可以对这个表进行加法操作。当两个表相加的时候,lua会检测两个表是否定义了元表,如果定义了就会找元表的__add方法是否为空,如果不为空就调用该方法。这种修改表的行为的操作很像c++中的运算符重载。
在lua中,可以用setmetatable(table, metatable)方法设置元表,tmeta = getmetatable (tab)返回table的元表。举一个简单的例子,实现两个表相加:
local t1 = {a = 2}local t2 = {a = 3}mt = {}mt.__add = function(tb1, tb2)local temp_t = {}temp_t.a = tb1.a + tb2.areturn temp_tendsetmetatable(t1, mt)local t3 = t1 + t2print(t3.a) --输入结果为5
类似的元方法还有很多,如:
算术元方法:__add  __mul  __ sub  __div  __unm  __mod  __pow  (__concat)
关系元方法:__eq __lt(<) __le(<=),其他Lua自动转换 a~=b --> not(a == b) a > b --> b < a a >= b --> b <= a 【注意NaN的情况】

今天的重点是__index元方法。当查询表中一个不存在的字段时,会先查询有没有设置元表,如果没有设就返回nil,如果设置了元表,就查询元表中__index是否为空,不为空则返回__index。__index既可以返回一个表,也可以返回一个函数。
有了这个元方法,我们就可以用它来实现类与对象。
local mt = {a = 10, b = 20} --我们定义自己的元表,里面可以有一些变量或者方法,让各个对象可以访问function mt:print_ab()print(self.a, self.b)endmt.__index = mt --定义元表mt的元方法__indexlocal o_tb_1 = {c = 30} --创建对象setmetatable(o_tb_1, mt) --设置元表,其实就是访问o_tb_1的a和b时,映射到mt的a和bo_tb_1:print_ab()o_tb_1.a = 100o_tb_1:print_ab()local o_tb_2 = {c = 30} --创建另一个对象setmetatable(o_tb_2, mt) --设置元表,其实就是访问o_tb_1的a和b时,映射到mt的a和bo_tb_2:print_ab()o_tb_2.a = 200o_tb_2:print_ab()


其实质就是元表mt的内容保持不变,共享给o_tb_1和o_tb_2,o_tb_1和o_tb_2通过__index映射到mt,访问mt的内容。

我们可以进一步封装一下:
local LuaClass = {m_a = 10, m_b = 20} --定义类function LuaClass:New(o) --定义类创建对象的方法o = o or {}setmetatable(o, self) --此处self指的是LuaClassself.__index = selfreturn oendfunction LuaClass:print_ab()print(self.m_a, self.m_b)end--调用local o_tb_1 = LuaClass:New()o_tb_1:print_ab()o_tb_1.m_a = 100o_tb_1:print_ab()local o_tb_2 = LuaClass:New()o_tb_2:print_ab()o_tb_2.m_a = 200o_tb_2:print_ab()


如果要实现继承的话可以这样:
local ChildClass = LuaClass:New({m_c = 30}) --创建子类function ChildClass:print_ab()print(self.m_a, self.m_b, self.m_c)endlocal o_tb_1 = ChildClass:New()o_tb_1:print_ab()o_tb_1.m_a = 100o_tb_1:print_ab()local o_tb_2 = ChildClass:New()o_tb_2:print_ab()o_tb_2.m_a = 200o_tb_2:print_ab() 


看上去类和对象的概念混为一谈,但是也没有办法,lua毕竟不是真正的面向对象。
0 0
原创粉丝点击