Lua is not really an object-oriented language, and it doesn't have a built-in concept of classes. But it is easily possible to create your own class system using tables and metatables.
Lua不是一个真正的面向对象语言,在Lua语言本身没有提供内置类的概念。但是,在Lua中很容易通过Table和Metatable来实现自己的面向对象机制。注:在Lua的演化文章中,作者解释了Lua没有提供内置类概念的原因。
local MyClass = {} -- the table representing the class, which will double as the metatable for the instances
MyClass.__index = MyClass -- failed table lookups on the instances should fallback to the class table, to get methods
MyClass.__tostring=function()
return "MyClass"
end
-- syntax equivalent to "MyClass.new = function..."
function MyClass.new(init)
local self = setmetatable({}, MyClass)
self.value = init
return self
end
function MyClass.set_value(self, newval)
self.value = newval
end
function MyClass.get_value(self)
return self.value
end
local i = MyClass.new(5)
-- tbl:name(arg) is a shortcut for tbl.name(tbl, arg), except tbl is evaluated only once
print(i:get_value()) --> 5
i:set_value(6)
print(i:get_value()) --> 6
创建MyClass Table来描述类模型,MyClass Table 的元方法__index 为自己。然后设置MyClass Table作为对象的metatable.所以当在对象中查找不到对应的方法时,在MyClass 中查询方法。
例如:
MyClass.__tostring=function()
return "MyClass"
end
在MyClass中增加__tostring元方法时,但是object实例对象中却没有__tostring()字段属性。当调用tostring()方法时,就会答应Object的内存地址。
当MyClass中增加__toring()方法后,调用tostring(object)就会调用MyClass方法。
print(tostring(i))
print(i)
In the methods, we use a "self" parameter to get the instance to operate on. This is so common that Lua offers the
:
syntax sugar that calls a function entry from a table and inserts the table itself before the first arg.
在定义方法时,self就是作为实例的参数。self在Lua中是一个很常见的语法糖。
我们可以通过__call元方法来改变,当一个值像函数一样调用的默认行为。
--设置元方法的__call
setmetatable(MyClass, {
__call = function (cls, ...)
return cls.new(...)
end,
})
local instance = MyClass(5)
print(instance)
Every value in Lua can have a metatable. This metatable is an ordinary Lua table that defines the behavior of the original value under certain special operations. You can change several aspects of the behavior of operations over a value by setting specific fields in its metatable. For instance, when a non-numeric value is the operand of an addition, Lua checks for a function in the field "__add"
in its metatable. If it finds one, Lua calls this function to perform the addition.
在Lua语言中,每一个值都有一个metatable。metatable就是一个普通的Table,但是metatable可以定义值的指定几个原始行为。可以通过改变metatable中字段来改变指定默认行为。例如:当一个没有+运算符操作时,Lua将检查是否存在metatable以及metatable中的__add字段属性。如果找到指定字段,则执行__add方法。