基础概念

LUA类的实现

Lua中的table是一个对象。拥有状态,拥有self,拥有独立于创建者和创建地的生命周期。

一个类就是一个创建对象的模具。Lua没有类的概念,但可以模拟类。

元表和元方法和模拟类有关,Lua 本身是函数式的语言,但借助 metatable (元表)这个强大的工具,Lua 实现操作符重载易如反掌。就像两个表相加,只要我们在元表中写上 __add 方法就可以实现了。

meta={
	__add=function(op1,op2)
		op = {}
		op.x = op1.x + op2.x
		op.y = op1.y + op2.y
		return op
	end
}
a={x=1,y=1}
setmetatable(a,meta)
b={x=3,y=4}
c = a + b
print(c.x, c.y) -- 输出 4,5 建立自己的类

通过这个方法,可以定义“类”的构造函数,析构函数。

除了与操作符重载有关的元方法以外,要建立自己的类,就不得不认识另外一个元方法 “__ index”。当表格搜寻成员未果的时候,Lua 会触发它,__ index 所指向的元方法,元方法所返回的结果就成为了搜寻结果。如果没有这个元方法,那么访问结果为 nil。__index元方法还可以直接为一张表。

假设要创建一些描述窗口的table,每个table中必须描述一些窗口参数,例如位置、大小及主题颜色等。所有这些参数都有默认值,因此希望在创建窗口对象时可以仅指定那些不同于默认值的参数。我们让新窗口从一个原型窗口处继承所有不存在的字段。首先,声明一个原型和一个构造函数,构造函数创建新的窗口,并使它们共享一个元表:

Window = {} --创建一个名字空间
--使用默认值来创建一个原型
Window.prototype = {x=0,y=0,width=100,height=100}
Window.mt = {} --创建元表
--声明构造函数
function Window.new(o)
	setmetatable(o,Window.mt)
	return o
end
定义__index元方法:
Window.mt.__index = function(table,key)
	return Window.prototype[key]
end

在这段代码之后,创建一个新窗口,并查询一个它没有的字段:

w = Window.new{x=10,y=20}
print(w.width) -->100

若Lua检测到w中没有某字段,但在其元表中却有一个__index字段,那么Lua就会以w(table)和"width"(不存在的key)来调用这个__index元方法。随后元方法用这个key来索引原型table,并返回结果。
在Lua中,将__index元方法用于继承是很普遍的方法,因此Lua还提供了一种更便捷的方式来实现此功能。__index元方法不必一定是一个函数,它还可以是一个table。当它是一个函数时,Lua以table和不存在的key作为参数来调用该函数,这就如同上述内容。而当它是一个table时,Lua就以相同的方式来重新访问这个table。因此,前例中__index的声明可以写为:

Window.mt.__index = Window.prototype
现在可以写一个简历的类:
A = {x=0,y=0}
--这句是重定义元表的索引,必须要有,
A.__index = A

--模拟构造体,一般名称为new()
function A:new(x,y)
        local self = {}
        setmetatable(self, A)   --必须要有
        self.x = x
        self.y = y
        return self
end

function A:test()
    print(self.x,self.y)
end

objA = A:new(1,2)
objA:test()
print(objA.x,objA.y)

posted @   请明月  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示