lua中点号和冒号的用法以及面向对象编程的基本实现原理

这篇博客介绍了Lua中的面向对象编程,包括封装、继承、多态和抽象等概念。文章详细阐述了如何在Lua中实现面向对象,如用table表示对象属性和function作为方法,通过元表模拟继承,以及如何解决全局污染问题。通过对比不同版本的方法调用,强调了冒号在函数调用中的作用,即自动传递self参数。最后,探讨了利用表、元表和元方法在Lua中实现类机制的基本原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Lua面向对象编程

一、面向对象特征

封装:指能够把一个实体的信息、功能、响应都装入一个单独的对象中的特性

继承:继承的思路允许在不改变源程序的基础上对其进行扩充 使得原功能得以保存,新功能得以扩展

多态:同一操作作用于不同的对象 可以有不同的解释 产生不同的执行结果 在运行时 可以通过基类的指针来调用实现派生类的方法

抽象:简化复杂的显示问题的途径 可以为具体问题找到最恰当的类定义 可以在最恰当的继承级别解释问题

二、面向对象简单实现

1.对象由属性和方法组成 lua用table来描述对象的属性 用function描述对象的方法
2.继承则可以通过元表模仿
3.lua中的表也有状态 --- 不同的成员变量 

--全局对象版

Windows1 = {width = 100, height = 200 }
function Windows1.setWidth(width)
    Windows1.width = Windows1.width + width
end

function Windows1.setheight(height)
    Windows1.height = Windows1.height + height
end

Windows1.setWidth(50)
Windows1.setheight(50)
print(Windows1.width)
print(Windows1.height)

缺点:

创建名为Windows1的对象 并且设置了一个方法 setWidth(width) setheight(height)
缺点 对象Role是以全局变量的方式创建的 会有一种“全局污染”的威胁 
全局污染:变量Role在其他地方被重新赋值(例如赋值为nil) 对象里的属性或者方法会面临被销毁或不能正常工作的情况
解决方法:提供一种“接受者”的解决方法 额外添加一个参数self来表示对象本身

第二版:提供接受者版 缺点 需要手动传入self 将点号用冒号代替 

Windows2 = {width = 100, height = 200 }
function Windows2.setWidth(self, width)
    Windows2.width = self.width + width
end

function Windows2.setHeight(self, height)
    Windows2.height = self.height + height
end

w = Windows2
w.setWidth(w, 200)
w.setHeight(w, 400)

print(Windows2.width)
print(Windows2.height)

优雅的第三版 原理:在函数定义时 使用冒号函数内部会有隐藏的self

--优雅的第三版

Windows3 = {width = 100, height = 200 }
function Windows3:setWidth(width)
    Windows3.width = self.width + width
end

function Windows3:setHeight(height)
    Windows3.height = self.height + height
end

w = Windows3
w:setWidth(200)
w:setHeight(400)

print(Windows3.width)
print(Windows3.height)

其中 w.setWidth (w, 300) 就等价于w:setWidth(300) 原理 函数调用时 使用冒号会默认传入一个参数(调用者自身)self

三、lua实现类机制

类实现原理 :通过表table 元表metatable 元方法metamethod 封装一个类

--Base原型表 用来描述一个类 在原型表中填写类方法 类属性则声明在狗子哦啊函数的新表中
Base = {} 
--实例化对象时 创建一个新表 将新标的元表设置为 原型表
function Base.new(self)
	--创建新表 并且声明自己的属性信息 即就是成员变量
	local ntable = {x = 0, y = 0}
	--将新表的元表设置为原型表
	setmetatable(ntable, Base)
	self. __index = self
	return	ntable
end
--函数定义时 使用点号 内部不存在self 所以需要手动传入
function Base.setXY(self, x, y)
	self.x = x
	self.y = y
end

function Base.printXY(self)
	print("x = "..self.x)
	print("y = "..self.y)
end

local object1 = Base:new()
--函数调用时 使用冒号 会自动传入一个调用者自身的参数 刚好是我们想要的结果
object1:setXY(199, 200)
object1:printXY()

--未调用设置方法 即为查看默认属性
local object2 = Base:new()
object2:printXY()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值