注: 原文有些地方不够详细或不正确,我补充完善了一些内容,如仍有不正确的地方,欢迎指正.
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 self end function ClassYM:test() print(self.x,self.y) end objA = 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 self end function ClassYM:test(sender) print(sender.x,sender.y) end objA = ClassYM:new(1,2) selfA = objA objA.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. 继承
--声明了新的属性Z Main = {z=0} --设置类型是Class setMetatable(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 self end --定义一个新的方法 function Main:go() self.x = self.x + 10 end --重定义父类的方法 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 = Class function Class:new(x,y) local self = {} setMetatable(self,Class) self.x = x self.y = y return self end function Class:test() print(self.x,self.y) end --新定义的一个函数gto() function Class:gto() return 100 end --这里会引用gto() function Class:gio() return self:gto() * 2 end function Class:plus() self.x = self.x + 1 self.y = self.y + 1 end继承部分代码如下:
Main = {z=0} setMetatable(Main,Class) Main.__index = Main function Main:new(x,z) local self = {} self = Class:new(x,y) setMetatable(self,Main) self.z= z return self end --重新定义了gto() function Main:gto() return 50 end function Main:go() self.x = self.x + 10 end function 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())具体结果大家可以自己试试看!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。