lua 是一种脚步语言,语言本身并不具备面向对象的特性。
但是我们依然可以利用语言的特性,模拟出面向对象的特性。
面向对象的特性通常会具备:封装,继承,多态的特性,如何在lua中实现这些特性,最主要的就是利用了lua的table和metatable。
table是一种强大的关联数组,它可以使用数字和字符串做key,而且可以使用点操作符访问table的元素,因此非常使用用于存储一个对象的属性;
metatable依然可以认为是一种关联数组,但是元表的作用更加强大,主要是:
1.定义算术操作符和关系操作符的行为
2.为 Lua 函数库提供支持
3.控制对 table 的访问
利用这个特性,我们可以把某个对象的方法存在元表中,当访问对象的方法时,如果自身不具备这个方法,就会在元方法中去寻找,因此利用元表可以轻松实现继承和多态的特性;
关于lua的具体实现:
-- 检查类名是否合法,要求是字符串 function validateClassName(className) local _type = type(className); if (_type == "string") then local _len = string.len(className) if (_len <= 40) then return true else print("[error] class name length is greater than 40") return false end else print("[error] class name of class is not a string") return false end end -- 检查属性表是否合法,属性只允许是基本类型(包括number,boolean,string,table,nil) function validatePropTabel(propTable) for _, _v in pairs(propTable) do local _propType = type(_v); if (_propType == "number" or _propType == "boolean" or _propType == "string" or _propType == "table" or _propType == "nil") then return true else print("[error] prop of class only support base type(number, boolean, string, table, nil), current type is ".._propType) return false end end end -- 检查父类是否合法,父类目前只支持table类型 function validateSuperClass(superClass) local _superType = type(superClass) if (_superType == "table" or _superType == "nil") then return true else print("[error] super class is not a table") return false end end -- className: 创建新类的类名 -- propTable: 新类的属性 -- superClass: 父类 function class(className, propTable, superClass) print("------------------------------------------------------") print("[info] create new class <"..className..">:") -- 验证参数合法性 if (not validateClassName(className) or not validatePropTabel(propTable) or not validateSuperClass(superClass)) then return nil else print("[info] arguments validated") end -- 创建新类 local subClass = {} -- 设置类名 subClass.__className = className -- 设置元方法 subClass.__index = subClass -- 设置属性表 subClass.props = propTable -- 设置父类 if (superClass) then setmetatable(subClass, superClass) subClass.super = superClass print("[info] extended from super class "..superClass.__className) else subClass.super = nil print("[info] super class is nil") end -- 设置默认构造函数 if (not subClass.ctor) then subClass.ctor = function(...) print(className.." default construct...") end print("[info] add default constructor") end -- 设置默认的析构函数 if (not subClass.dtor) then subClass.dtor = function() print(className.." default destruct...") end print("[info] add default destructor") end -- 设置new方法 subClass.new = function(...) -- 创建一个新的实例 local instance = {} -- 继承父类默认的属性 local _cls = subClass.super while (_cls) do if (_cls.props) then print("------------------------------------------------------") print("[info] extended prop from super class <".._cls.__className..">:") for _k, _v in pairs(_cls.props) do print("[info] ".._cls.__className.." key:"..tostring(_k).." value:"..tostring(_v)) instance[_k] = _v end print("------------------------------------------------------") end _cls = _cls.super end -- 设置本类的属性 if (propTable) then print("------------------------------------------------------") print("[info] extended prop from super class <"..className..">:") for _k, _v in pairs(propTable) do print("[info] "..className.." key:"..tostring(_k).." value:"..tostring(_v)) instance[_k] = _v end print("------------------------------------------------------") end -- 设置实例的元表为本类 setmetatable(instance, subClass) -- 调用实例的构造函数 instance:ctor(...) print("[info] create instance of class <"..className..">") return instance end -- 设置delete方法 subClass.delete = function(instance) -- 调用实例的析构函数 instance:dtor() -- 删除实例的数据 print("------------------------------------------------------") print("[info] delete prop from super class <"..className..">:") for _k, _v in pairs(instance) do print("[info] "..className.." key:"..tostring(_k).." value:"..tostring(_v)) instance[_k] = nil end print("------------------------------------------------------") -- 删除实例的元表 setmetatable(instance, nil) -- 删除实例 instance = nil print("[info] delete instance of class <"..className..">") end print("------------------------------------------------------") return subClass end