LUA 构造类

来源:互联网 发布:红警2 mac os10.12 编辑:程序博客网 时间:2024/05/22 23:27

15年11月写的这份代码,现在开源出来作为技术文档,希望大家能够看到帮助更多的人清晰的理解LUA元表。

1.首先,是我设计类的整体构造,解析给大家看,需要考虑对象创建出来不能够再去执行 new 等关键词,为此我为其添加了索引保护代码。

--[[@格式--]]--[[Proto = {__index = <Proto>,__metatable = <string>,__add = <function>,__tostring = <function><metatable> = {__metatable = <string>,__tostring = <function>}}Class = {__index = <function>,__newindex = <function>,__metatable = <string>,__className = <string>,__prototype = <Proto>,__isInherit = <boolean>,new = <function>,super = <table>,init = <function>,<metatable> = <Proto>}instance = {class = <Class>,<metatable> = <Class>}--]]

2.接下来是真正的安全的类的代码。

--[[@关键字 class@参数 className <string>@参数 super <table>--]]class = function (className)local newProto = function ()local Proto = setmetatable({}, {__metatable = "Warning: can't change proto",__tostring = function ()return "proto"end})Proto.__metatable = "Warning: can't change class"Proto.__index = function (table, key)--保护数据local protectList = {"__index", "__metatable", "__add", "__tostring"}if table.__prototype thenfor _, value in pairs(protectList) doif key == value thenreturn nilendendendreturn Proto[key]endProto.__add = function (first, second)local checkSuper; checkSuper = function (super, second)--检测first.super是否存在secondfor __, value in pairs(super) doif value == second thenreturn trueendif value.super thenif checkSuper(value.super, second) then--递归检测return trueendendendreturn falseendlocal addSuper = function (first, second)table.insert(first.super, second)--添加superfor key, value in pairs(second) do--添加方法if not first[key] thenfirst[key] = valueendendreturn firstendif type(second) ~= "table" then--检测类型print("Error : super is not class")return nilendif not second.__isInherit then--不可继承print("Warning : [" .. second.__className .. "] is can't inherit")return firstendif first.super then--检测super是否存在if checkSuper(first.super, second) then--检测second是否被继承print("Warning : [" .. second.__className .. "] is already inherit")return firstendelsefirst.super = {}endif second.__prototype then--是否为classfirst = addSuper(first, second)elsefor _, value in pairs(second) doif value.__prototype thenfirst = addSuper(first, value)elseprint("Error : super is not class list")return nilendendendreturn firstendProto.__tostring = function (table)return "class: " .. table.__classNameendreturn Protoendlocal Proto = newProto()--构造protolocal Class = setmetatable({}, Proto)Class.__prototype = ProtoClass.__metatable = "Error: can't change instance"Class.__className = classNameClass.__isInherit = true--可否被继承Class.__index = function (table, key)--保护数据local protectList = {"new", "super", "init", "__index", "__newindex", "__prototype", "__metatable", "__className", "__isInherit"}if table.class then--是否为实例for _, value in pairs(protectList) doif key == value thenreturn nilendendendreturn Class[key]endClass.__newindex = function (table, key, value)print("Error: can't change instance")endClass.new = function (...)local init; init = function (class, ...)local super = class.superif super thenfor _, value in pairs(super) doinit(value, ...)--递归初始化superendendif class.init thenprint(class.__className .. " init")class:init(...)endendlocal instance = {class = Class}setmetatable(instance, Class)init(instance.class, ...)--初始化实例return instanceendreturn Classend

3.测试类及其对象

local A = class("A")A.init = function(self)print("A:init")self.test = 0endA.Test = function(self)print("Test", self.test)endlocal B = class("B") + AB.init = function(self)print("B:init")print(tostring(self.super))self.test = 1endB.Print = function(self, ...)for _, value in ipairs(arg) doprint(value)endendlocal b = B.new()b:Test()b:Print("a")print(tostring(b.class))





原创粉丝点击