加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Lua 中实现类

发布时间:2020-12-14 21:58:38 所属栏目:大数据 来源:网络整理
导读:Lua中是没有类的概念的,但是程序猿说要面向对象,所以就有了。 首先来看创建一个 Person 表,拥有一个name的key,默认Value为 "chenpeng" Person = {name="chenpeng"} 也就是说 Person 拥有一个 name 属性。 再在 Person 表中添加一个键 talk , 值为一个函

Lua中是没有类的概念的,但是程序猿说要面向对象,所以就有了。


首先来看创建一个 Person 表,拥有一个name的key,默认Value为 "chenpeng"

Person = {name="chenpeng"}

也就是说 Person 拥有一个 name 属性。


再在 Person 表中添加一个键 talk , 值为一个函数

Person.talk=function( self,words )
	-- body
	print(self.name	.. "说" ..words)
end

好了,我们调用

Person.talk(Person,"你好")

得到结果打印出

chenpeng说你好

不过大家都习惯把 function 写在前面,所以有函数语法糖

--talk其实是Person表中的一个键,对应的值为一个函数

--函数语法糖 function放前面
function Person.talk( self,words )
	-- body
	print(self.name	.. "说" ..words)
end

Person.talk(Person,"你好")

但是每次都传个 self 实在是闲的蛋疼。。所以有 冒号语法糖

--冒号语法糖,Lua会自动将self作为第一个参数,self代表的是这个函数的实际调用者
function Person:talk( words )
	-- body
	print(self.name	.. "说" ..words)
end

Person:talk("你好")

上面 三段代码都是等价的,只是运用了 函数语法糖? 和 冒号语法糖


metatable 和 __index

Lua的表进行查找一个 键 对应的值时,进行了如下操作

比如在 表 p 中找有没有 talk 这个键。

首先在 p 中寻找,如果 p 中就有,就返回 talk 对应的值

如果p中没有,就去 metatable 中看有没有 __index 这个键 如果有就去 __index 这键对应的表中找

如果__index中有 就返回? getmetatable(p).__index.talk


__index 有点像父类的感觉


metatable

metatable叫元表,其实就是一个表。

元表的作用是增加和改变表的既定操作,只有设定过元表的表,才会受到元表的影响而改表自身的行为。


通过全局方法 setmetatable(t,m) 就可以将表 t 的元表设置为表 m。

通过全局方法 getmetatable(t) 就可以返回 t 的元表。


注意:所有的表都能设置元表,新创建的空表如果不设置元表,是没有元表的。


__index

设置元表 真正设置的是 Lua 规定的元方法 键值对。就是 Lua 规定的键,例如 __index,__add,__concat等,都以 __为前缀

其对应的值为一个函数,被称为? 元方法 (metamethod),这些元方法定义了你想对表自定义的操作。


例如__index ,在Lua中它所对应的元方法执行的触发条件是 查找不存在于表中的键时 ,然后执行某些操作。

然后我们可以让 在表中查找不存在表中的键时 , 提示一个错误

Person = {name="chenpeng"}

--冒号语法糖,Lua会自动将self作为第一个参数,self代表的是这个函数的实际调用者
function Person:talk( words )
	-- body
	print(self.name	.. "说" ..words)
end

Person.__index=function( table,key )
	return "没有这个键"
end


--表pos
pos = {}
--设置pos的元表为Person
setmetatable(pos,Person)
--pos中没有age,但是因为设置了元表,所以去元表中的__index找age,但是元表中也没有age,所以触发自定义操作
print(pos.age)

类的实现

了解上面的一些基础知识后,大致可以推测出类的实现方法。

例如Person类,Person类是一个表。

我们创建一个 Person 的实例,其实也是一个表,例如表 person1 ={}

但是person1 是个空表哇,怎么让他拥有 Person的属性呢?

给person1 设置元表为 Person 就好了。在person1中找不到的 键 就会去Person 的 __index 中找了。然后把 Person的 __index 设置为自身 Person 表。


Person.lua

Person = {name="chenpeng"}


--原版
--[[
Person.talk=function( self,"你好")

--]]

--talk其实是Person表中的一个键,对应的值为一个函数

--函数语法糖 function放前面
--[[function Person.talk( self,"你好")

--]]


--冒号语法糖,Lua会自动将self作为第一个参数,self代表的是这个函数的实际调用者
function Person:talk( words )
	-- body
	print(self.name	.. "说" ..words)
end


--定义元表的__index 的元方法
--对任何找不到的键,都会返回'undefined'
Person.__index=Person


function Person:Create( name )
	-- body
	local p = {}
	setmetatable(p,Person)
	p.name=name
	return p
end


--return person  --返回这个表


创建 test.lua 来调用

require("Person")

local p={}
setmetatable(p,Person)

p.name="chenpeng1"
p:talk("我是路人已")

local p1={}
setmetatable(p,Person)
p.name="chenpeng2"
p:talk("我是路人已")

local p3 = Person:Create("chenpeng3")
p3:talk("我是路人丙")

代码下载

http://pan.baidu.com/s/1pJOT5nd
http://download.csdn.net/detail/cp790621656/9238057

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读