面向对象
代码语言:javascript复制--保存类类型的虚表
local _class = {}
-- added by wsh @ 2017-12-09
-- 自定义类型
ClassType = {
class = 1,
instance = 2,
}
function BaseClass(classname, super)
assert(type(classname) == "string" and #classname > 0)
-- 生成一个类类型
local class_type = {}
-- 在创建对象的时候自动调用
class_type.__init = false
class_type.__delete = false
class_type.__cname = classname
class_type.__ctype = ClassType.class
class_type.super = super
class_type.New = function(...)
-- 生成一个类对象
local obj = {}
obj._class_type = class_type
obj.__ctype = ClassType.instance
-- 在初始化之前注册基类方法
setmetatable(obj, {
__index = _class[class_type],
})
-- 调用初始化方法
do
local create
create = function(c, ...)
if c.super then
create(c.super, ...)
end
if c.__init then
c.__init(obj, ...)
end
end
create(class_type, ...)
end
-- 注册一个delete方法
obj.Delete = function(self)
local now_super = self._class_type
while now_super ~= nil do
if now_super.__delete then
now_super.__delete(self)
end
now_super = now_super.super
end
end
return obj
end
local vtbl = {}
-- added by wsh @ 2017-12-08
assert(_class[class_type] == nil, "Aready defined class : ", classname)
_class[class_type] = vtbl
setmetatable(class_type, {
__newindex = function(t,k,v)
vtbl[k] = v
end
,
--For call parent method
__index = vtbl,
})
if super then
setmetatable(vtbl, {
__index = function(t,k)
local ret = _class[super][k]
--do not do accept, make hot update work right!
--vtbl[k] = ret
return ret
end
})
end
return class_type
end
BaseView = BaseView or BaseClass("BaseView")
BaseView.a = 1
BaseView.b = 2
function BaseView:__init()
print("BaseView:__init")
end
function BaseView:__delete()
print("BaseView:__delete")
end
function BaseView:DoBaseFunc()
print("BaseView:DoBaseFunc")
end
function BaseView:DoSomething()
print("BaseView:DoSomething")
end
LoginView = LoginView or BaseClass("LoginView",BaseView)
function LoginView:__init()
print("LoginView:__init")
end
function LoginView:__delete()
print("LoginView:__delete")
end
function LoginView:DoSomething()
print("LoginView:DoSomething")
end
ologin_view = LoginView:New() -->BaseView:__init LoginView:__init
ologin_view:Delete() -->LoginView:__delete BaseView:__delete
print(ologin_view.a) -->1
ologin_view.a = 3
print(ologin_view.a) -->3
ologin_view.c = 4
print(ologin_view.c) -->4
print(BaseView.c) -->nil
print(ologin_view:DoBaseFunc()) -->BaseView:DoBaseFunc
print(ologin_view:DoSomething()) -->LoginView:DoSomething
访问基类成员方法
代码语言:javascript复制local function OnCreate(self)
self._class_type.super.OnCreate(self)
end
多态
子类直接写新函数名,覆盖父类
重载
代码语言:javascript复制-- 添加组件
-- 多种重载方式
-- 1、直接添加Lua侧组件:inst:AddComponent(ComponentTypeClass, luaComponentInst)
-- 2、指定Lua侧组件类型和必要参数,新建组件并添加,多种重载方式:
-- A)inst:AddComponent(ComponentTypeClass, relative_path)
-- B)inst:AddComponent(ComponentTypeClass, child_index)
-- C)inst:AddComponent(ComponentTypeClass, unity_gameObject)
local function AddComponent(self, component_target, var_arg, ...)
assert(component_target.__ctype == ClassType.class)
local component_inst = nil
local component_class = nil
if type(var_arg) == "table" and var_arg.__ctype == ClassType.instance then
component_inst = var_arg
component_class = var_arg._class_type
else
component_inst = component_target.New(self, var_arg)
component_class = component_target
component_inst:OnCreate(...)
end
local name = component_inst:GetName()
AddNewRecordIfNeeded(self, name)
RecordComponent(self, name, component_class, component_inst)
self.length = self.length 1
return component_inst
end
通过type 确定不同类型,进行访问
保护级别
Lua里面可以做到脚本级别的成员保护,分为:私有成员、公有成员。私有成员就是在脚本全局范围内定义的局部变量,而对于表来说,所有成员都是公有的。 A) 数据成员 私有数据成员,直接在脚本中local定义就行,如上面的基类base赋值语句,这个base就不能在其它脚本被访问到。 公有数据成员,需要写入虚表(对表进行赋值),使用self.xxx就行。 B) 成员函数 私有成员函数:目前的类定义,所有的函数我都是使用local定义的,使用local定义的function如果不写入虚表,那它就是私有的,这点和数据成员一样。 公有成员函数:如果想暴露某个成员函数成为公有函数,只需要在类定义底部写入虚表即可。 例如:
代码语言:javascript复制UIBaseContainer.OnCreate = OnCreate
UIBaseContainer.OnEnable = OnEnable
UIBaseContainer.Walk = Walk
UIBaseContainer.OnComponentSetName = OnComponentSetName
UIBaseContainer.OnComponentDestroy = OnComponentDestroy
UIBaseContainer.AddComponent = AddComponent
UIBaseContainer.GetComponent = GetComponent
UIBaseContainer.GetComponents = GetComponents
UIBaseContainer.GetComponentsCount = GetComponentsCount
UIBaseContainer.RemoveComponent = RemoveComponent
UIBaseContainer.RemoveComponents = RemoveComponents
UIBaseContainer.OnDisable = OnDisable
UIBaseContainer.OnDestroy = OnDestroy
return UIBaseContainer
单例
c#单例 使用GetInstance访问,每次只返回 唯一的new 的table
代码语言:javascript复制local function __init(self)
assert(rawget(self._class_type, "Instance") == nil, self._class_type.__cname.." to create singleton twice!")
rawset(self._class_type, "Instance", self)
end
local function __delete(self)
rawset(self._class_type, "Instance", nil)
end
local function GetInstance(self)
if rawget(self, "Instance") == nil then
rawset(self, "Instance", self.New())
end
assert(self.Instance ~= nil)
return self.Instance
end