Lua如何像C++一样面向对象,从问题出现到解决,逐步了解为什么lua需要实现类
admin
2024-03-29 09:04:00
0次

本文从以下几点分析逐步学习lua面向对象编程思想
1.怎么解除对象间的依赖关系
2.lua中的语法糖 ’ : ’
3.lua中类的概念
4.lua中的单继承怎么实现
5.lua中的多继承怎么实现

在多继承之前的内容,都很好理解
学习建议:以下所有代码皆可运行,将所有代码都实现一遍。

先展示问题所在,将test1赋值给tt ,但test1释放后(赋值nil可以理解为舍弃), 就会出错

-- 
test1 = {val = 10}
function test1.fun()test1.val = test1.val - 10print(test1.val)
end
tt = test1
-- test1 = nil -- 如果把这句开启 就会出错
-- 因为test1已经复制nil了,但tt.fun仍会调用它
tt.fun()

以下这种方式,多传一个参数,就能解决上边的问题

test1 = {val = 10}
function test1.fun(self) self.val = self.val + 20print(self.val)
end
tt = test1
test1 = nil	//就算赋值nil也不影响。
tt.fun(tt)

到这里,是不是觉得这个self功能其实很像C++中的this指针,就是将自己本身传递进去,lua中有一个语法糖’ : ’ 可以实现避免显式的写出self对象。

比如上边是 tt.fun(tt), 可以通过tt : fun(), 从而省去tt的传参

test1 = {val = 10}
function test1:fun()self.val = self.val + 10print("self:"..self.val) -- 如果把.. 换成, 相当于一个'\t'
endtt = test1
test1 = nil
tt:fun() 

是不是越来越有对象的感觉了。

lua中类的概念 : 我们需要实现一个类, 然后通过这个类来初始化一个对象
lua中面向对象的编程思想最重要的就是, 关于元表的设计,以及元方法(__index)的设计
比如 setmetatable(o, self) , self就是o的元表, 然后再给self设置元方法。
在下边的代码中 new() 函数相当于返回了一个我们需要的对象,关于这个对象所具有的功能,是封装在acount中的,所以我们可以把acount当作类。

local acount = {val = 10}
function acount:new(o)o = o or {}setmetatable(o, self)self.__index = selfreturn o
endfunction acount:display()self.val = self.val + 200print(self.val)
endlocal a = acount:new{val = 0}  -- a 就相当于 acount类的一个对象
--这里改成local a = acount:new() 看一下输出结果
--lua中当传参是一个表的时候可以省略 ()a:display() --等价a.display(a) -- 我这里是给了初始表 {val = 0},-- 若没有给初始表,比如上边换成acount:new(),则a本来是没有val对象的,a.val 就相当于 getmetatable(a).__index(val) 才能得到val --第一次调用display时,self.val 就是 a.val 尽管是去acount中获取的val,但是因为调用了a.val,就相当于在a中添加了一个新的字段val,当第二次调用display时,就不会去acout中寻找val字段了,而是直接用a对象自己的val

lua中的单继承实现
简单分析流程:先创建父类acount, 子类acount_son是通过acount:new()获得的

再通过acount_son:new () 返回的就是子类acount_son的一个对象

下边的代码中还实现了,在子类acount_son中重写父类acount的display方法。

local acount = {val = 10}
function acount:new(o)o = o or {}setmetatable(o, self)self.__index = selfreturn o
endfunction acount:display()self.val = self.val + 100print(self.val)
endacount_son = acount:new()
function acount_son:display()   -- 相当于类中的函数重写 self.val = self.val + 666print(self.val)
endins = acount_son:new()
ins:display() 
--  可以分析一下,ins.val第一次是没有的,先去acount_son再去acount找的
-- 同样ins.display也是一样, 但如过在acount_son中重写了display函数,就相当于实现了重写的效果

lua中的多重继承实现
简单流程分析: 通过上边的演示,我们已经知道了lua的面向对象实质上就是通过__index元方法实现的, 只是对于单继承,直接是self.__index = self,
而多继承中,不能直接 =self ,而是用一个函数,来遍历所继承的所有父类中的方法。

其实不用想的太复杂,多继承和单继承的本质区别就是

setmetatable(c, {__index = function(t,k) return search(k, parentlist) end})

在子类继承父类的时候(c继承CA,CB),不再是像单继承一样self.__index = self了
还有一个关键的细节点, c是子类,我们需要用c返回一个对象**,和单继承返回对象一样**,所以需要实现c:new() ,发现没有,单继承和多继承的区别就在于继承父类的时候__index的设置不同,但生成对象都是一样的方式

local function search(k, parentlist) for i = 1, #parentlist dolocal fun = parentlist[i][k]if fun thenreturn funendend
endfunction createclass(...)local parentlist = {...}local c = {}setmetatable(c, {__index = function(t,k) return search(k, parentlist) end})function c:new(o)o = o or {}setmetatable(o, self)self.__index = selfreturn oend-- 返回新的类return c
end-- 简单类CAlocal CA = {}
function CA:new(o) o = o or {}setmetatable(o, self)self.__index = selfreturn o
endfunction CA:SetName(strName) self.name = strName
end-- 简单类CB
local CB = {}
function CB:new(o) o = o or {}setmetatable(o, self)self.__index = self return o
endfunction CB:GetName()return self.name
end--创建一个c类, 它的父类是CA 和 CB 
local c = createclass(CA, CB) --使用c类创建一个实例对象
local objectc = c:new{name = "jj"} --设置objectc的新名字
objectc:SetName("dashuaigejj")
local newName = objectc:GetName()
print(newName)

相关内容

热门资讯

AI做攻略、“双向奔赴”……国... 本文转自:人民网人民网记者 许维娜今年国庆假期,AI(人工智能)成了不少年轻人的“旅行搭子”。行前做...
合肥的这个“梗”, 翻篇了 社交平台的评论区,曾长期流传一句专属于合肥的黑色幽默。有人问合肥哪里好玩,本地网友半开玩笑地回复:合...
7万+旅游中高层都在的群,今天... 做旅游这行,资源卡位、渠道互通、项目落地——往往就差一个“对的机会”。我们的行业社群已聚集70,00...
一场帐篷音乐节,如何让井研从“... 帐篷音乐节现场封面新闻记者 周洪攀10月的研溪湿地,晚风里裹着柑橘的清甜与民谣的回响。夜幕降临,10...
白鹤翩翩落星愿,上海迪士尼度假... 10月9日,世界候鸟日前夕,上海迪士尼度假区星愿公园的湖风里多了一分白鹤的灵动。三座白鹤雕塑正式揭幕...
成都锦江边赏初秋枫叶飘飘 目前,成都锦江边国华街枫叶树红了。近年来,国华街附近的几条街都栽种了红枫树,是城区较集中看枫叶的点位...
GBTA:商务旅行正在复苏,但... 亚太正在成为全球商务旅行增长的重要引擎。在经历疫情后的快速反弹之后,全球商务旅行正在进入一个新的增长...
从景区焕新到节赛引流 邹城双节... 齐鲁网·闪电新闻10月9日讯 中秋、国庆“双节”假期,邹城市文化和旅游局提前谋划、周密部署,立足自身...
江山如此多娇 且看石楼今朝 金秋十月,黄河岸畔秋意盎然,丰收盛会喜迎国庆。本次石楼国庆文旅活动以“江山如此多娇,且看石楼今朝”为...
海南国庆假期接待游客475.4... 2026年国庆假期,海南接待游客475.40万人次,较2025年增长13.1%,较2024年增长15...