Lua的类实现继承、多态以及setmetatable方法

Lua的类实现继承、多态以及setmetatable方法,第1张

概述注: 原文有些地方不够详细或不正确, 我补充完善了一些内容, 如仍有不正确的地方, 欢迎指正. 1. Lua类实现 从网上搜了几个类实现,自己照猫画老虎的弄个如下: ClassYM = {x=0, y=0}--这句是重定义元表的索引,必须要有,ClassYM.__index = ClassYM--模拟构造体,一般名称为new()function ClassYM:new(x,y)

注: 原文有些地方不够详细或不正确,我补充完善了一些内容,如仍有不正确的地方,欢迎指正.

1. Lua类实现

从网上搜了几个类实现,自己照猫画老虎的弄个如下:

ClassYM = {x=0,y=0}--这句是重定义元表的索引,必须要有,ClassYM.__index = ClassYM--模拟构造体,一般名称为new()function ClassYM:new(x,y)    local self = {}    setMetatable(self,ClassYM)   --必须要有    self.x = x    self.y = y    return selfendfunction ClassYM:test()    print(self.x,self.y)endobjA = ClassYM:new(1,2)objA:test()print(objA.x,objA.y)

运行结果如下:

1   2
1   2

print(objA:x,objA:y)会报错(注意这里是冒号,不是点!),调用ojbA.test也会报错(注意这里是点,不是冒号!),Why?

报错的信息是:
stdin:2: attempt to index local 'self' (a nil value)

self的值为空, 因为test()里缺少self的值,即为空,所以执行test内部语句时报错.

我们改造一下代码,如下:

ClassYM = {x=0,ClassYM)   --必须要有    self.x = x    self.y = y    return selfendfunction ClassYM:test(sender)    print(sender.x,sender.y)endobjA = ClassYM:new(1,2)selfA = objAobjA.test(nil,selfA)print(objA.x,objA.y)

运行结果如下:

1   2
1   2

这样就正确了,这里objA.test(nil,self)的第一个参数是传递进ClassYM:test()的self参数,这里为了区别,我们故意设为nil值,而第二个参数selfA才是传递给ClassYM:test()的sender参数,其实你可以把ClassYM:test(sender)中的sender改为self,这里是为了方便理解,因为这个sender不是用冒号时隐式的传递进来的self,而是objA.test(nil,selfA)的第二个参数. 所以建议还是使用冒号版的objA:test,方便得多,用点(".")会造成不必要的麻烦.

然而,我们再变换一下,如果调用

objA = ClassYM.new(1,2)    -- 注意这里是".",不是":"(冒号)!
再调用objA:test()  print(objA.x, objA.y)  时结果如下:

2  0
2  0

如调用

objA = ClassYM.new(self,1,2)   -- 注意这里是".",不是":"(冒号)!

再调用objA:test()   print(objA.x, objA.y)   时结果如下:

1  2
1  2

lua提供了用冒号的方式在一个方法定义中添加一个额外的参数,这个参数就是self,这句话可以不理解,但是要牢记!

继承和多态部分详见:http://www.soyomaker.com/forum.php?mod=viewthread&tid=230

2. 继承

--声明了新的属性ZMain = {z=0}--设置类型是ClasssetMetatable(Main,Class)--还是和类定义一样,表索引设定为自身Main.__index = Main--这里是构造体,看,加上了一个新的参数function Main:new(x,y,z)   local self = {}  --初始化对象自身   self = Class:new(x,y) --将对象自身设定为父类,这个语句相当于其他语言的super   setMetatable(self,Main) --将对象自身元表设定为Main类   self.z= z --新的属性初始化,如果没有将会按照声明=0   return selfend--定义一个新的方法function Main:go()   self.x = self.x + 10end--重定义父类的方法function Main:test()    print(self.x,self.y,self.z)end
测试代码如下:
c = Main:new(20,40,100)c:test()d = Main:new(10,50,200)d:go()d:plus()d:test()c:test()
3. 多态
Class = {x=0,y=0}Class.__index = Classfunction Class:new(x,y)        local self = {}        setMetatable(self,Class)        self.x = x        self.y = y        return selfendfunction Class:test()    print(self.x,self.y)end--新定义的一个函数gto()function Class:gto()   return 100end--这里会引用gto()function Class:gio()   return self:gto() * 2endfunction Class:plus()    self.x = self.x + 1    self.y = self.y + 1end
继承部分代码如下:
Main = {z=0}setMetatable(Main,Class)Main.__index = Mainfunction Main:new(x,z)   local self = {}   self = Class:new(x,y)   setMetatable(self,Main)   self.z= z   return selfend--重新定义了gto()function Main:gto()   return 50endfunction Main:go()   self.x = self.x + 10endfunction Main:test()    print(self.x,self.z)end

测试代码如下:

a = Class:new(10,20)print(a:gio())d = Main:new(10,200)print(d:gio())print(a:gio())
具体结果大家可以自己试试看!

转自: http://blog.csdn.net/ym012/article/details/7206968

  总结

以上是内存溢出为你收集整理的Lua的类实现继承、多态以及setmetatable方法全部内容,希望文章能够帮你解决Lua的类实现继承、多态以及setmetatable方法所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1266853.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存