有一篇博客对Lua元表的介绍非常易懂,推荐阅读原博主的文章 点我前往
以下内容仅仅是个人为了加深记忆将原博主内容消化并复述一遍。
lua元表就是用于查找的备用表。如果访问table中不存在的字段,不会立即返回nil,而是先触发一套查找机制,查找它的元表。
举例:
local fathermayun = {
money = 13000000000
}
--设置fathermayun的__index元方法
fathermayun.__index = fathermayun
local me = {}
--将fathermayun设为me的元表
setmetatable(me, fathermayun)
print(me.money)
--输出:13000000000
Lua 查找一个表元素时的规则,其实就是如下 3 个步骤:
1.在表中查找,如果找到,返回该元素,找不到则继续
2.判断该表是否有元表,如果没有元表,返回 nil,有元表则继续。
3.判断元表有没有 __index 方法,如果 __index 方法为 nil,则返回 nil;如果 __index 方法是一个表,则重复 1、2、3;如果 __index 方法是一个函数,则返回该函数的返回值。
利用元表的上述特性实现面向对象的继承特性
local function class( super )
local cls
if super then
cls = {}
cls.super = super
setmetatable(cls, {__index = super})
else
-- ctor是构造函数的命名
cls = {ctor = function () end}
end
cls.__index = cls
function cls.new( ... )
local instance = setmetatable({}, cls)
instance:ctor()
return instance
end
return cls
end
测试继承
local Test = class()
function Test:doSomething()
print("test doSomething")
end
local Test2 = class(Test)
local test = Test2.new()
test:doSomething()
也可以成功打印出"test doSomething"
原理说明:
在new的时候,创建一个table并返回,即创建一个实例,实例可以有自己的字段,比如Test类的doSomething,该字段是个函数,可以调用执行。实例的元表是cls,如果调用实例没有的字段,会去cls里找
cls设置了元方法__index = cls
如果没有super,则只有一个构造函数方法
如果有super,cls的元表是super,元表的元方法也正确的设置了
所以,在Test2是继承自Test的,它的实例test调用doSomething,找不到,去元表里找,元表发现自己有父类,去父类里找,成功找到。
网友评论