1.继承
1.1 关键字Class
使用Class关键字来继承是规范的做法
不用担心父类的方法无法访问
甚至貌似可以不用设置元表和__index
如
local TestBaseClass = class("TestBaseClass")
local TestExtendClass = class("TestExtendClass" , TestBaseClass)
实例化类的对象可以用new方法
local t = TestExtendClass.new()
1.2 关键字super
local ext = TestExtendClass.new()
print("ext start")
ext.super.Fun1(ext)
ext:Fun1()
print("ext" , ext.super.val)
print("ext" , ext.val)
[LUA-print] ext start
[LUA-print] TestBaseClass.Fun1 val_of_TestBaseClass
[LUA-print] TestExtendClass.Fun1 val_of_TestExtendClass
[LUA-print] ext val_of_TestBaseClass
[LUA-print] ext val_of_TestExtendClass
可见,父类中的方法和属性,都可以通过super访问到
1.3 getmetatable
local p = {}
这时getmetatable(p)返回nil
local p= class("p")
这时getmetatable(p)返回一个table
可以理解为class关键字更规范的定义了类
类有new方法,但普通对象则没有
1.4 setmetatable
local TempBase = {
b = "TempBase_b"
}
local TempClass = {
a = "Aa"
}
setmetatable(TempClass , {
__index = TempBase
})
print("TempClass" , TempClass.a)
print("TempClass" , TempClass.b)
[LUA-print] TempClass Aa
[LUA-print] TempClass TempBase_b
对象也可以使用继承
更准备的理解是扩展这个对象本身
若对象x继承自对象a,则必须使用语法
setmetatable(x, {
__index = a
})
若对象x继承自类A,则可以像上面那样写
也可以简单写做setmetatable(x, A)
继承是可以层层传递的
1.5 __metatable
在Lua中,函数setmetatable和getmetatable函数会用到元表中的一个字段,用于保护元表,该字段是__metatable。当我们想要保护集合的元表,是用户既不能看也不能修改集合的元表,那么就需要使用__metatable字段了;当设置了该字段时,getmetatable就会返回这个字段的值,而setmetatable则会引发一个错误;如以下演示代码:
function Set.new(l) local set = {} setmetatable(set, mt) for _, v in pairs(l) do set[v] = true end mt.__metatable = "You cannot get the metatable" -- 设置完我的元表以后,不让其他人再设置 return set end local tb = Set.new({1, 2}) print(tb) print(getmetatable(tb)) setmetatable(tb, {})
上述代码就会打印以下内容:
{1, 2}
You cannot get the metatable
lua: test.lua:56: cannot change a protected metatable
1.6 __index
使用class关键字继承的情况下,似乎完全不需要处理__index元方法
其描述如下
当访问一个table的字段时,如果table有这个字段,则直接返回对应的值;
当table没有这个字段,则会促使解释器去查找一个叫__index的元方法,接下来就就会调用对应的元方法,返回元方法返回的值;
如果没有这个元方法,那么就返回nil结果。
可以用__index为对象赋上 默认 属性/方法集合
因为Lua以table和"不存在key"作为参数来调用该函数,所以若访问的是"存在的key",则不会使用默认值
__index原方法是metatable中的一个元方法,并不是直接在对象上
参考http://www.jellythink.com/archives/511