您的位置:首页 > 编程语言 > Lua

Lua 中实现类

2015-11-03 18:30 309 查看
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,words )
-- body
print(self.name .. "说" ..words)
end

Person.talk(Person,"你好")

--]]

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

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

Person.talk(Person,"你好")

--]]

--冒号语法糖,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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: