注: 原文有些地方不够详细或不正确,我补充完善了一些内容,如仍有不正确的地方,欢迎指正.
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 21 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
继承和多态部分详见: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方法所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)