您的位置:首页 > 编程语言 > Lua

LUA 构造类

2017-08-11 04:02 274 查看
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 then
for _, value in pairs(protectList) do
if key == value then
return nil
end
end
end

return Proto[key]
end

Proto.__add = function (first, second)
local checkSuper; checkSuper = function (super, second)	--检测first.super是否存在second
for __, value in pairs(super) do
if value == second then
return true
end

if value.super then
if checkSuper(value.super, second) then	--递归检测
return true
end
end
end
return false
end

local addSuper = function (first, second)
table.insert(first.super, second)	--添加super

for key, value in pairs(second) do	--添加方法
if not first[key] then
first[key] = value
end
end

return first
end

if type(second) ~= "table" then	--检测类型
print("Error : super is not class")
return nil
end

if not second.__isInherit then	--不可继承
print("Warning : [" .. second.__className .. "] is can't inherit")
return first
end

if first.super then	--检测super是否存在
if checkSuper(first.super, second) then	--检测second是否被继承
print("Warning : [" .. second.__className .. "] is already inherit")
return first
end
else
first.super = {}
end

if second.__prototype then	--是否为class
first = addSuper(first, second)
else
for _, value in pairs(second) do
if value.__prototype then
first = addSuper(first, value)
else
print("Error : super is not class list")
return nil
end
end
end

return first
end

Proto.__tostring = function (table)
return "class: " .. table.__className
end

return Proto
end

local Proto = newProto()	--构造proto

local Class = setmetatable({}, Proto)

Class.__prototype = Proto
Class.__metatable = "Error: can't change instance"
Class.__className = className
Class.__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) do
if key == value then
return nil
end
end
end

return Class[key]
end

Class.__newindex = function (table, key, value)
print("Error: can't change instance")
end

Class.new = function (...)
local init; init = function (class, ...)
local super = class.super

if super then
for _, value in pairs(super) do
init(value, ...)	--递归初始化super
end
end

if class.init then
print(class.__className .. " init")
class:init(...)
end
end

local instance = {
class = Class
}

setmetatable(instance, Class)
init(instance.class, ...)	--初始化实例

return instance
end

return Class
end

3.测试类及其对象

local A = class("A")

A.init = function(self)
print("A:init")
self.test = 0
end

A.Test = function(self)
print("Test", self.test)
end

local B = class("B") + A

B.init = function(self)
print("B:init")
print(tostring(self.super))
self.test = 1
end

B.Print = function(self, ...)
for _, value in ipairs(arg) do
print(value)
end
end

local b = B.new()
b:Test()
b:Print("a")

print(tostring(b.class))
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息