lua类与对象

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.a
		return temp_t
	end
	setmetatable(t1, mt)
	
	local t3 = t1 + t2
	print(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)
	end
	mt.__index = mt --定义元表mt的元方法__index
	
	local o_tb_1 = {c = 30} --创建对象
	setmetatable(o_tb_1, mt) --设置元表,其实就是访问o_tb_1的a和b时,映射到mt的a和b
	o_tb_1:print_ab()
	o_tb_1.a = 100
	o_tb_1:print_ab()
	
	local o_tb_2 = {c = 30} --创建另一个对象
	setmetatable(o_tb_2, mt) --设置元表,其实就是访问o_tb_1的a和b时,映射到mt的a和b
	o_tb_2:print_ab()
	o_tb_2.a = 200
	o_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指的是LuaClass
		self.__index = self
		return o
	end
	
	function 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 = 100
	o_tb_1:print_ab()
	
	local o_tb_2 = LuaClass:New()
	o_tb_2:print_ab()
	o_tb_2.m_a = 200
	o_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)
	end
	
	local o_tb_1 = ChildClass:New()
	o_tb_1:print_ab()
	o_tb_1.m_a = 100
	o_tb_1:print_ab()
	
	local o_tb_2 = ChildClass:New()
	o_tb_2:print_ab()
	o_tb_2.m_a = 200
	o_tb_2:print_ab() 


看上去类和对象的概念混为一谈,但是也没有办法,lua毕竟不是真正的面向对象。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值