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

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

运行结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/63304.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

线性回归方程模型

一、项目要求 以个人为单位,实现AI识别的算法: 调查某市出租车使用年限和该年支出维修费用(万元),得到数据如下: 使用年限(x) 2 3 4 5 6 维修费用(y) 2.2 3.8 5.5 6.5 7.0 求线性回归方程由1中结论预测第10年所支出的维修费用 3.说明自己选中预测的原因和过程中的收获 说…

【OpenDRIVE_Python】使用python脚本读取txt指定内容,输出OpenDRIVE数据中对应的信息

示例代码说明: 读取txt指定内容如地物id,输出OpenDRIVE数据中的对应地物id和名称name信息为xml文件 import xml.dom.minidom from xml.dom.minidom import parse from xml.dom import Node import sys import os # 读取OpenDRIVE文件路径 xml_filepath…

什么是DBD设备?

2022年10月,本号文章《北斗优先是对北斗三代的挑衅》中指出:“多系统兼容互操作是北斗三号逐步替代北斗二号的主要原因。北斗优先是对北斗三代的挑衅。”现在想来,当时还是太年轻,格局没有打开。 2023年12月,本号文章…

uviewplus中的时间单选框up-datetime-picker的在uni-app+vue3的使用方法

uviewplus中的时间单选框up-datetime-picker的使用方法 前言 在实际开发中,我们经常需要使用时间选择器来让用户选择特定的时间。本文将详细介绍uviewplus中up-datetime-picker组件的使用方法,特别是在处理年月选择时的一些关键实现,因为官方有很多相关的功能和方法…

高质量翻译在美国推广移动应用中的重要性

美国的移动应用市场是世界上竞争最激烈、利润最高的市场之一,为开发者提供了接触数百万潜在用户的机会。然而,进入这个市场需要的不仅仅是创新技术或令人信服的想法;它要求与目标受众进行有效地沟通和文化契合。在这个过程中,高质…

基于Python的PDF批量转化工具

一、开发的缘由 最近,有网友想让我帮他做一个批量把png, docx, doc, pptx, ppt, xls, xlsx文件转化为PDF格式的软件,完全傻瓜式的操作,把文件拖进去就进行转化那种,简单实用。之前,有过一个vbs的文件,可以…

模型案例:| 手机识别模型!

导读 2023年以ChatGPT为代表的大语言模型横空出世,它的出现标志着自然语言处理领域取得了重大突破。它在文本生成、对话系统和语言理解等方面展现出了强大的能力,为人工智能技术的发展开辟了新的可能性。同时,人工智能技术正在进入各种应用领…

【Copilot 】TAB keybinding not working on JetBrains Client

pycharm ssh 远程到ubuntu24.04 发现tab就是tab,无法输出copilot给出的自动补全到便捷器里。禁用host的copilot插件,重新启动ide就好了。解决办法 参考大神的办法删除主机和客户端插件中的 Copilot插件。 仅在客户端中重新安装 Copilot 插件。 我只是禁用也可以 对比了键盘映…

【Linux】程序的编译过程

程序的翻译过程 预处理(头文件展开,条件编译,宏替换,去注释)编译 :把c变成汇编语言汇编 :把汇编变成二进制(不可执行,二进制目标文件)链接 :把自…

Trunk链路操作题

Trunk链路操作题 论证:

【计算机网络】实验7:默认路由和特定主机路由以及路由环路问题

实验 7:默认路由和特定主机路由以及路由环路问题 一、 实验目的 了解默认路由以及特定主机路由。 了解静态路由配置错误导致的路由环路问题。 二、 实验环境 • Cisco Packet Tracer 模拟器 三、 实验内容 1、默认路由以及特定主机路由 (1) 第一步&#xff…

特殊的数学性质

一个数模9的结果等于它的每一位数相加和模9

JSP知识点总结

jsp九大对象 在jsp中内置了9个对象,无需创建该对象即可使用。其名称为固定名称。 1.out输出对象 - 属于JspWriter print(): 输出 flush(): 刷新 close(): 关闭 2.request请求对象 - 属于HttpServletRequest getParameter(): 获取请求的参数 setCharacterEncodin…

电子信息工程自动化 基于单片机的居室安全报警系统

摘要 本课题设计了基于STM32F103C6T6单片机为主控核心的居室安全报警系统。为了解决家庭居室的安全监控,通过温湿度芯片SHT30、烟雾传感器MQ-2、天然气传感器MQ-4来获取居室的温湿度、烟雾、天然气含量,使用了一个热释电传感器、菲涅耳透镜、红外传感信…

【vue3 for beginner】Pinia基本用法:存储user的信息

🌈Don’t worry , just coding! 内耗与overthinking只会削弱你的精力,虚度你的光阴,每天迈出一小步,回头时发现已经走了很远。 📗概念 Pinia 简介 Pinia 是一个用于 Vue.js 应用的状态管理库,是 Vuex 的…

使用Goland对6.5840项目进行go build出现异常

使用Goland对6.5840项目进行go build出现异常 Lab地址: https://pdos.csail.mit.edu/6.824/labs/lab-mr.html项目地址: git://g.csail.mit.edu/6.5840-golabs-2024 6.5840运行环境: mac系统 goland git clone git://g.csail.mit.edu/6.5840-golabs-2024 6.5840 cd 6.5840/src…

React基础知识四 Hooks

什么是hooks? (coderwhy) hooks是react 16.8(2019年)出的新特性。 react有两种形式来创建组件——类式和函数式。在hooks之前类式组件就是react最主流的编程方式。 这个时候,函数式组件是非常鸡肋的,几乎没什么用。因…

电子病历静态数据脱敏路径探索

一、引言 数据脱敏(Data Masking),屏蔽敏感数据,对某些敏感信息(比如patient_name、ip_no、ad、no、icd11、drug等等 )通过脱敏规则进行数据的变形,实现隐私数据的可靠保护。电子病历作为医疗领…

AIGC 012-Video LDM-更进一步,SD作者将LDM扩展到视频生成任务!

AIGC 012-Video LDM-Stable Video diffusion前身,将LDM扩展到视频生成任务! 文章目录 0 论文工作1论文方法实验结果 0 论文工作 Video LDM作者也是Stable diffusion的作者,作者在SD的架构上进行扩展,实现了视频的生成。后续在Vid…

ABAP DIALOG屏幕编程1

一、DIALOG屏幕编程 DIALOG屏幕编程是SAP ABAP中用于创建用户交互界面的一种技术,主要用于开发事务性应用程序。它允许用户通过屏幕输入或操作数据,程序根据用户的操作执行逻辑处理。 1、DIALOG编程的主要组件 a、屏幕 (Screen) DIALOG程序的核心部分…