print("******* OO *******")
-- 面向对象
-- print("******* 封装 *******")
-- 所有面向对象、类,其实都是基于 table 来实现
-- 以及 元表相关知识点
Object = {}
Object.id = 1 -- 类似与c#的静态方法
function Object:Test()
print(self.id)
end
-- 实现一个实例化方法
-- 冒号 是会自动将调用这个函数的对象作为第一个参数传入的写法
function Object:new()
-- self 代表的是我们传入的第一个参数
-- 对象就是变量,即返回一个新的变量
-- 返回出去的内容,本质上就是 table 对象
-- 注意是 local, 否则 obj 是全局变量
local obj = {}
-- 元表知识, __index 当找自己的变量找不到时,就会去找元表当中 __index 指向的内容
-- 这样就可以在生成的实例对象中得到 id 的值
self.__index = self
setmetatable(obj, self) -- 由于之后要继承,这里不能直接写 Object
return obj
end
local myObj = Object:new()
print(myObj)
print(myObj.id) -- 通过元表来进行访问
-- 这里调用 self 时是在 myObj 表中寻找 id 属性,找不到通过 __index 从 Object 中寻找
myObj:Test()
-- 相当于是对 new 方法中的空表 obj 进行操作,声明一个新的属性
-- 与 Object 中的 id 没关系
myObj.id = 2
print(Object.id, myObj.id)
-- 这里调用 self 时直接在 myObj 表中寻找已有的 id 属性
myObj:Test()
-- print("******* 继承 ******")
-- C# class 类名 : 继承类
-- Lua 中写一个用于继承的方法
-- 首先补充 _G 表的一种使用方法,可以直接在 _G 表中添加元素
print(_G)
_G["a"] = 1
_G.b = "123"
print(a)
print(b)
function Object:subClass(className)
-- _G 知识点:总表,所有声明的全局变量,都以键值对的形式存储
_G[className] = {}
-- 写相关继承的规则
-- 用到元表
local obj = _G[className]
self.__index = self
-- 子类定义一个 base 属性代表父类,以在多态中使用
obj.base = self
setmetatable(obj, self)
end
-- 声明一个 Object 的子类 Person,其元表为 Object,且 __index = Object
Object:subClass("Person")
print(Person)
print(Person.id)
-- 通过实例化, 这里的过程是:
-- Person 调用 new 方法,由于 Person 中没有 new 方法, 根据其元表的 __index 去寻找,
-- 而 Person 是由 Object:subclass 中添加的,其元表为 Object, 且在 subClass 中设置其 __index
-- 是 Object,因此 Person 调用 Object 的 new() 方法中返回一个空表,并且在 new 方法中 self
-- 其实为 Person,在该方法中,返回的 obj(即p1) 的元表为 Person, __index 也是 Person
-- 元表关系即为: obj(p1) -> Person -> Object
-- | |
-- __index 关系: Person Object
--
local p1 = Person:new()
-- 首先 p1 实际上是通过 new 方法返回的空 talbe, 其中没有 id 属性,那么就要通过其元表的 __index
-- 去寻找,而 Person 中也没有该属性,因此通过 __index 的嵌套最后从 Object 中去寻找 id
print(p1.id) -- 实际为 Object 的 id
p1.id = 100
print(p1.id) -- p1 自己的 id
-- print("******* 多态 *******")
-- 相同行为,不同表现就是多态
-- 相同方法,不同执行逻辑,就是多态
Object:subClass("GameObject")
GameObject.posX = 0
GameObject.posY = 0
function GameObject:move()
self.posX = self.posX + 1
self.posY = self.posY + 1
print(self.posX, self.posY)
end
GameObject:subClass("Player")
local p1 = Player:new()
p1:move() -- 调用的 GameObject 中的 move 方法
-- 直接重写 move 方法实现多态
function Player:move()
-- C#中通过 base 保留父类的方法. base.move()
-- 因此需要构建一个 base
-- 此处 base 指的是 GameObject 表(类)
-- 这种方式调用相当于是把基类表作为第一个参数传入
-- 注意,此处是通过 base 调用父类 GameObject 中的 move 方法
-- 而不是通过 元表的 __index, 因此调用的 move 中的 self 并不是
-- Player 而是 GameObject,会导致后面的一个【坑】
self.base:move()
end
p1:move()
-- !!!! 大坑
local p2 = Player:new()
-- 与 p1:move() 打印的结果不一致
-- p1:move() 打印的是 (1, 1); p2:move() 打印的是 (2,2)
-- 因为此时 p1,p2 是对 GameObject 中同一个 posX,posY 进行修改
-- 即不同对象使用的是 同一个成员变量
-- 原因是在 move 中调用时通过 base 是调用同一个 GameObject 的 move 方法
-- 修改的也是 GameObject 中的 posX,posY
p2:move() -- (2,2)
p1:move() -- (3,3)
-- 因此要避免把基类表传入到方法中
-- 如果要执行父类逻辑,不要直接使用冒号调用,把调用者自己当作第一个参数传入
function Player:move()
self.base.move(self)
end
local p3 = Player:new()
local p4 = Player:new()
-- 这里的步骤是:
-- 调用 move 的时候传入的是 self,即 p3, 也是 GameObject 中的 self
-- 在 self.posX = self.posX + 1 式子中, p3 一开始没有 posX 变量,
-- 通过元表得到 GameObject 的 posX 的值然后加1,赋值给 self.posX 左值
-- 此时 p3 就有了新的变量 posX,即自己的变量,而不是 GameObject 的
p3:move()
p4:move()
p3:move()
-- 总结
print("******* OO All *******")
-- 封装、继承、多态汇总
-- 万物之父 所有对象的基类 Object
Object = {}
-- 实例化方法
function Object:new()
local obj = {}
self.__index = self
-- 给空对象设置元表 以及 __index 对象
setmetatable(obj, self)
return obj
end
-- 继承
function Object:subClass(className)
-- 根据名字生成一张表
_G[className] = {}
local obj = _G[className]
-- 设置自己的“父类”
obj.base = self
-- 给子类设置元表 以及 __index
self.__index = self
setmetatable(obj, self)
end
-- 声明一个新的类
Object:subClass("GameObject")
GameObject.posX = 0
GameObject.posY = 0
function GameObject:move()
self.posX = self.posX + 1
self.posY = self.posY + 1
end
-- 实例化对象使用
local obj = GameObject:new()
print(obj.posX)
obj:move()
print(obj.posX)
local obj2 = GameObject:new()
print(obj2.posX)
obj2:move()
print(obj2.posX)
-- 多态
-- 声明一个新类 Player 继承 GameObject
GameObject:subClass("Player")
-- 重写 move 方法
function Player:move()
-- base 调用父类方法用 . 自己传第一个参数
self.base.move(self)
end
-- 实例化 Player 对象
local p1 = Player:new()
local p2 = Player:new()
print(p1.posX)
print(p2.posX)
p1:move()
p2:move()
print(p1.posX)
print(p2.posX)
相关推荐
Lua教程(十): 全局变量和非全局的环境
主要介绍了Lua教程(十): 全局变量和非全局的环境,本文讲解了老的全局变量环境和Lua5中新的非全局环境相关知识,需要的朋友可以参考下
lua 遍历 table
Lua常用的4中遍历方式 for key, value in pairs(tbtest) do XXX end 这样的遍历顺序并非是tbtest中table的排列顺序,而是根据tbtest中key的hash值排列的顺序来遍历的。 for key, value in ipairs(tbtest) do XXX end 这样的循环
告别环境报错:用Pycharm一站式搞定Superset 3.0.0二次开发环境(Windows/Mac通用)
本文详细介绍了如何使用Pycharm一站式搭建Apache Superset 3.0.0的二次开发环境,涵盖Windows和Mac平台。通过虚拟环境配置、依赖管理、数据库初始化及前后端协同开发等步骤,帮助开发者高效解决环境报错问题,提升开发效率。特别适合需要进行Superset二次开发的工程师参考。
Lua中的非全局变量
第一天入职游戏公司,主管让我学习lua,大部分时间都花在解决面向对象编程和安装lua与C交互的环境了 作为程序员没有自己的技术日志怎么行,今天就来吐槽一下lua学习时候采的坑 -- Meta class Shape = {area = 0} -- 基础类方法 new function Shape:new (o,side) o = o or {} setmetatable(o, self) self.__index = self side = side or 0 self.area = s...
AI人工智能全模态大模型架构:推动智能交通发展的架构设计
本文旨在阐述全模态大模型在智能交通领域的架构设计原理和应用方法。我们将探讨如何利用多模态AI技术解决交通流量预测、事故预警、路线优化等关键问题。文章将从基础概念入手,逐步深入技术细节,最后探讨实际应用和未来发展方向。全模态大模型:能够处理和理解多种数据模态(如图像、文本、语音等)的大型AI模型智能交通系统(ITS):利用先进技术优化交通流量和安全性的综合系统多模态融合:将不同数据源的信息整合处理的技术核心概念回顾全模态大模型是能够处理多种数据类型的强大AI系统。
K8s入门教程(一)
本教程提供了Kubernetes(K8s)的入门指南,涵盖了从基础概念到实战操作的全面内容。首先介绍了Kubernetes的定义和核心功能,如自动化部署、弹性伸缩、自我修复等。接着,详细讲解了如何在macOS上安装Minikube和kubectl工具,以及如何使用这些工具创建和管理Pod、Deployment和Service等核心资源。教程还包括了实战案例,如部署Nginx应用,并介绍了高级特性如滚动更新和自动伸缩。最后,提供了常见问题的解决方案,帮助用户快速上手和解决实际使用中的问题。
lua class 怎么遍历成员列表_UE4 Unlua UObject绑定lua脚本
UObject-LuaInstance布局思维导图:在Unlua框架下, 每个UObject在创建的时候都会尝试绑定一个lua脚本.UObject-LuaInstance布局调用堆栈UObject绑定Lua基础在创建UObject的时候会对所有继承了FUObjectCreateListener的对象, 调用函数NotifyUObjectCreated, 在销毁UObject的时候同样会对继承了FU...
保姆级教程:Synology NAS共享文件夹从创建到权限设置的完整流程
本文提供了一份详尽的Synology NAS共享文件夹创建与权限设置指南。重点讲解了如何将NAS接入企业AD域,并利用域管理员账户进行集中身份验证和权限管理。文章从基础概念、域环境配置、文件夹创建、精细化权限分配到客户端访问与维护,完整覆盖了构建安全高效企业级文件共享空间的全流程,旨在帮助管理员实现便捷的团队协作与数据安全管理。
lua的全局变量、局部变量、函数闭包和非局部变量(upvalue)
我们知道lua脚本语言的变量是弱类型的,即变量没有类型,值才有类型,同一名称的变量具体类型要看所赋值的类型,如下 a=1 --整型 a=1.0 --浮点型 a="ab" --string型 a={} --table型 a=function() ... end --function型 全局变量和局部变量,类似于shell脚本 全局变量:顾名思义,其生命有效期是全局的,整个lua
世界模型(World Models)进展全景调研(截至 2025-08)
A5) 2019-07(待核验) | C-SWM:Contrastive Structured World Models(Kipf et al.)A6) 2019-07(待核验) | SLAC:Stochastic Latent Actor-Critic(Lee et al.)A3) 2015-12(背景注记,待核验) | Embed to Control(E2C,Watter et al.)Nature 2020)Repro/Code:werner-duvaud/muzero-general(社区)
Autosar 下电过程-基于ETAS工具
本文介绍基于ETAS工具对应的BIP包的下电过程,仅供参考。在最后调用SBC下电时,需要理清楚SBC的休眠流程,否则可能会出现休眠又唤醒情况。后面有空会介绍9471的休眠流程。
静态、常量、局部、全局变量
1 静态、常量、局部、全局变量
基于 STM32 的校园电动车充电桩智能计费与过载保护系统设计与实现
本系统基于 STM32F103 主控,通过 HLW8032 电能计量芯片实现精准计费,配合继电器实现过载保护,RC522 模块完成刷卡身份识别,整体方案成本低、可靠性高,适合校园电动车集中充电场景的批量部署。软件采用状态机设计,逻辑清晰,可扩展多路充电口、远程监控等功能。
Lua 面向对象
面向对象编程(Object Oriented Programming,OOP)是一种非常流行的计算机编程架构,通过创建和操作对象来设计应用程序。Lua 是一种轻量级的脚本语言,虽然它不像 Java 或 C++ 那样内置强大的面向对象(OO)特性,但它非常灵活,可以通过一些技巧实现面向对象编程。
YOLOv8改进 | 主干网络 | 在backbone添加Swin-Transformer层【论文必备】
YOLOv8改进,Swin-Transform,YOLOv8添加Swin-Transform
jre9下载 jdk9
(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】
Lua语言实现面向对象
文章目录前言一、Lua中的数据类型二、_G三、元表四、面向对象1.封装2.继承3.多态总结 前言 Lua是一种轻量级的脚本语言,在unity开发中经常用来做热更新相关的解决方案,我们现在的程序开发往往都是面向对象的,而Lua中是不存在类的概念的,让我们来看一下在Lua中如何实现面向对象编程。 一、Lua中的数据类型 Lua中共有8种数据类型,简单数据类型:number、boolean、string、nil,复杂数据类型:function、userdata、thread、table。Lua中没有类的概念,
温度PID控制PLC程序
温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值
Lua如何实现面向对象
众所周知,Lua作为一种很小却很灵活的脚本语言,如今广泛应用于各种网游的热更新。毕竟是解释型语言嘛,不需要提前编译。我们可以把它打成AssetBundle,现场解压运行。 但是,相信很多做游戏开发的童鞋,从C#等强类型语言转去写Lua代码的时候,可能都感叹过,Lua真难用!!!找个引用要找半天,还经常打错字段,更重要的是,它不支持面向对象啊!我本来就是单身,你还要剥夺我new对象的权利吗?╥﹏╥ 不过,随着对Lua的深入♂了解,我发现它还是很迷人的,而且,以上问题前辈们早就有了解决方案。 本文就来谈谈
Camera2Demo
在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作
lua面向对象
lua面向对象:封装、继承、多态
Lua之面向对象的实现
Lua本身是不支持面向对象的,但是可以利用table和元表、元方法进行面向对象的模拟! 以下是Cocos2d-lua中面向对象的实现: class function class(classname, ...) local cls = {__cname = classname} local supers = {...} for _, super in ipairs(supe...
【lua学习】Lua 面向对象
【lua学习】Lua 面向对象 面向对象编程(Object Oriented Programming,OOP)是一种非常流行的计算机编程架构。 以下几种编程语言都支持面向对象编程: C++ Java Objective-C Smalltalk C# Ruby 面向对象特征 1) 封装:指能够把一个实体的信息、功能、响应都装入一个单独的对象中的特性。 2) 继承:继承的方法允许在不改动原...
一篇文章理解Lua面向对象
Lua的类 个人觉得Lua并不能算是一门面向对象的语言;因为Lua它是定位于开发中小型程序,往往不会用于编写大型程序; 下面这是一个Lua中的一个简单的类的实现 local a = {name="lisi"} function a:new( o ) o = o or {} setmetatable(o,self) self.__index = self return o end function a:MyPrint( ) print(self.name) end local tb =
Lua学习笔记七——lua也面向对象
lua也面相对象?不错,是的。它有面向对象的操作。看看简单示例:CTest = { cnt = 0 }function CTest:new(o) o = o or {} setmetatable(o, self) self.__index = self return oendfunction CTest.add(self, v) self.cnt = s
Lua学习随感之一关于Lua面向对象的理解
前言 靠着零碎的时间学习,今天可算是把Lua面向对象的基本原来给搞明白了,有一种守得云开见月明的感觉,没理解之前感觉很难,看哪里哪里都蒙蔽。理解了之后就感觉其实也没这么难 引用 我们知道,对象由属性和方法组成。LUA中最基本的结构是table,所以需要用table来描述对象的属性。 lua 中的 function 可以用来表示方法。那么LUA中的类可以通过 table + function 模拟出来。 至于继承,可以通过 metetable 模拟出来(不推荐用,只模拟最基本的对象大部分时间够用了)。 关于L
Lua的面向对象封装
lua这款简洁优雅的语言,非常受C/C++程序员喜欢。然而lua由于太过小巧,其接口过于类似汇编,使用困难,容易出错,也让人无可奈何。 随着C++11的推进,lua逐渐出现了诸多非常有特色的面向对象封装方式,经过封装后,接口非常的简单优雅,而且操作简便,深受C++程序员的欢迎。
621



被折叠的 条评论
为什么被折叠?



