首页 文章 LUA面向对象-类的实现
源码:
local type = type
local setmetatable = setmetatable
local string_format = string.format
---
--- 类声明接口
function _G.class(name, defClass)
local obj = _G._class_list[name]
if obj then
_error("Class Already exist ", name)
return obj
end
obj =
{
_newCount = 0, -- 对象创建数量
_class = name, -- 类名
_super = nil, -- 继承的父类对象
-- new 创建对象
new = function(self, ...)
self._newCount = self._newCount + 1
local classobj = self
local newfunc = classobj[classobj._class]
if not newfunc and self ~= classobj then
_error("class new func not find:%s:%s()", classobj._class, classobj._class)
return nil
end
local newobj, defobj = newfunc(classobj, ...)
if not defobj then
defobj = newobj
else
for k, v in pairs(newobj) do
if not defobj[k] then -- 父对象不能覆盖子对象的数据
defobj[k] = v
end
end
end
defobj._new_index = self._newCount
setmetatable(defobj, self)
return defobj
end,
--- 继承
--@param super string/table/userdata
extend = function(self, super)
if type(super) == "string" then
super = _G._class_list[super]
end
self._super = super
if not super.__index then
setmetatable(self, {__index = super})
else
setmetatable(self, super)
end
return self
end,
-- 默认打印显示类名
__tostring = function(self)
if self._new_index then
return string_format( "[class]%s:%s", self._class, self._new_index) -- 对象显示guid
else
return string_format( "[class]%s", self._class)
end
end
}
if defClass then
table.clone(obj, defClass)
end
obj.__index = obj
_G[name] = obj
return obj
end
使用示例
local CTest1 = class "CTest1"
function CTest1:CTest1(x)
return {
x = x,
callCount = 0
}
end
function CTest1:call()
self.callCount = self.callCount + 1
return self.callCount
end
function CTest1:call1()
return 100
end
function CTest1.__add(a, b)
return {x = a.x + b.x}
end
local CTest2 = class "CTest2" : extend "CTest1"
function CTest2:CTest2(y)
return {
y = y
},
CTest2._super:new(y * 10) -- or CTest1:new(y * 10)
end
function CTest2:call()
CTest2._super.call(self) -- 手动调用父类函数 or CTest1.call(self)
self.callCount = self.callCount + 1
return self.callCount
end
function CTest2:call2()
return 200
end
local CTest3 = class "CTest3" : extend "CTest2"
function CTest3:CTest3( z )
return {z=z},
self._super:new(z*10)
end
function CTest3:call3()
return 300
end
CTest1:new(1)
CTest1:new(1)
local obj1 = CTest1:new(1)
local obj2 = CTest2:new(2)
local obj3 = CTest3:new(3)
print(obj1, obj2, obj3)
print("test call:", obj3:call())
print("test class1 :", obj1.x, obj1:call1())
print("test class2 :", obj2.x, obj2.y, obj2:call1(), obj2:call2())
print("test class3 :", obj3.x, obj3.y, obj3.z, obj3:call1(), obj3:call2(), obj3:call3())