您的位置:首页 > 新闻 > 会展 > 南京做网站的公司排名_企业网络安全管理_腾讯会议价格_开封网站推广公司

南京做网站的公司排名_企业网络安全管理_腾讯会议价格_开封网站推广公司

2024/12/27 3:54:20 来源:https://blog.csdn.net/m0_46210273/article/details/144302923  浏览:    关键词:南京做网站的公司排名_企业网络安全管理_腾讯会议价格_开封网站推广公司
南京做网站的公司排名_企业网络安全管理_腾讯会议价格_开封网站推广公司

Lua面向对象 实现 超详细注释 实现构造函数,析构函数,只读类模板等功能

源码

-- 注意下面的代码可以拆开成多个文件使用,也可以放一起
-- Class.lualocal _class = {}-- 将Source变成只读表并返回
function MakeTableReadOnly(Source)local proxy = {}local mt = {}mt.__index = Sourcemt.__newindex = function()print("ReadOnly!")endsetmetatable(proxy,mt)return proxy
end-- 返回class_type作为类模板,类模板可用来创建对象
function class(super)local class_type = {}-- ctor为构造函数class_type.ctor = false-- close为析构函数class_type.close = false-- super为父类,也是一个class_typeclass_type.super = super-- 类模板提供一个创建类实例的方法class_type.new = function(...)-- object为返回的类实例local object = {}-- create用于从父类一直递归的调用构造函数,c是class_typelocal createcreate = function(c,...)if c.super thencreate(c.super, ...)endif c.ctor thenc.ctor(object, ...)endend-- 调用构造函数create(class_type,...)-- 构建元表local mt = {}-- 如果访问object中没有的对象,那么就访问_class[class_type],这样就实现了成员的继承mt.__index = _class[class_type]-- 析构函数local close_function = function(...)local destorydestory = function(c,...)if c.close thenc.close(object,...)endif c.super thendestory(c.super,...)endenddestory(class_type, ...)end-- 当类实例被gc掉时,触发close_functionmt.__gc = close_function-- 设置元表setmetatable(object, mt)return objectend-- vtbl用于存放类模板的公用不可变成员,也就是类的成员(这里存放的是类中不可修改的,公用的部分,通常是函数或者常数)local vtbl = {}-- 类模板的成员不可修改_class[class_type] = MakeTableReadOnly(vtbl)-- 对类模板的新建值操作,实际上会存到vtbl中,可以实现函数的覆盖setmetatable(class_type, {__newindex = function(t,k,v)rawset(vtbl,k,v)end})-- 如果有父类if super then-- 如果访问类模板成员表中没有,就访问父类模板成员表setmetatable(vtbl, {__index = function(t,k)local res = _class[super][k]-- 下面这行可以加可以不加,加上的话,这里会将父类的成员直接拷贝到子类中,之后再次访问的话效率会提高。但是热更新的情况下如果父类模板修改,子类不会修改。-- rawset(vtbl,k,res)return resend})end-- 返回类模板return class_type
end-- Base.lua
-- 创建类模板
Base = class()-- 这里不会触发class_type的__newindex元方法,因为class_type中已经有了
function Base:ctor(x)print("Base:ctor")-- 这里的self是类实例,而不是类模板,因为这个函数由上面的create调用,create传递的参数是object(类实例),根据:操作符,self就是objectself.x = x
end-- 同理不会触发__newindex元方法
function Base:close(x)print("Base:close")
end-- 这里会触发class_type的__newindex元方法,将Hello方法加入到_class[class_type](也就是vtbl)中
function Base:Hello()print("Base:Hello")
end-- SubBase.lua
-- 创建SubBase 继承于 Base
SubBase = class(Base)-- 同理不会触发__newindex元方法
function SubBase:ctor(x,y)print("SubBase:ctor")-- 这里的self是SubBase的类实例对象,由于create是递归的调用ctor方法,所以self中既有x也有y。-- 为何要这样,通过ctor中使用self的这种方式,每个类实例对象的成员都是不同的,修改成员时不会相互影响self.y = y
end-- 同理不会触发__newindex元方法
function SubBase:close(x)print("SubBase:close")
end-- 这里实现了Hello函数的override,原理是vtbl绑定了__index元方法,只有__index元方法只有找不到的时候,才会返回父类成员
-- 由于class_type实现了__newindex方法,这里定义的函数会向vtbl中写入,从而实现函数的override
function SubBase:Hello()print("SubBase:Hello")
end-- 向vtbl中写入
function SubBase:SubHello()print(self.x)print(self.y)
end-- Test.lua
-- 注意这里要使用.而不是:
-- 创建类实例
Test = Base.new(1)
Test2 = SubBase.new(1,2)Test:Hello()
Test2:Hello()
Test2:SubHello()-- 尝试修改类模板的成员
getmetatable(Test2)["__index"].Hello = function()print("want to change!")
end

运行结果

在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com