COCOS2D-X Lua面向对象编程

上次有个同学问我,说lua太简单了,没有什么结构,也不好做面向对象编程。其实可以这样说,Lua中的table就是一个对象。



下面我一点一点介绍Lua的面向对象编程。


一、对象的方法函数:
[cpp]  view plain copy
  1. Hero = {attack = 100}  
  2.   
  3. function Hero.skill(addAttack)  
  4.   Hero.attack = Hero.attack + addAttack  
  5. end  
  6.   
  7. Hero.skill(20)  
  8. print(Hero.attack)  --> 120  

上面的先创建了一个函数,并调用该函数。


仔细的同学可能发现了,调用函数的时候使用了全局Hero。我在上一篇细节介绍中提过,Lua尽量减少全局变量的使用。而且这里也有风险,一不小心修改了Hero,可能Hero就不能正常工作了。


那么联想到上一篇写到的local temA =  A,有人可能想到了这样修改上面的函数调用:
[cpp]  view plain copy
  1. oneHero = Hero;   
  2. Hero = nil  
  3. oneHero.skill(30)  
  4. print(oneHero.attack) --> 错误,oneHero为nil  

这样也是错误的。因为Hero已经为nil了。


正确的如何修改呢?我们可以使用this/self 来实现:
[cpp]  view plain copy
  1. Hero = {attack = 100}  
  2.   
  3. function Hero.skill(self,addAttack)  
  4.   self.attack = self.attack + addAttack  
  5. end  
  6.   
  7. oneHero = Hero;   
  8. Hero = nil  
  9. oneHero.skill(oneHero,30)  
  10. print(oneHero.attack)   --> 130  

OK,这下可以了,但是self每次需要自己传,看着就麻烦,其实Lua也可以隐性调用self,我们在修改下:
[cpp]  view plain copy
  1. Hero = {attack = 100}  
  2.   
  3. function Hero:skill(addAttack)  
  4.   self.attack = self.attack + addAttack  
  5. end  
  6.   
  7. oneHero = Hero;   
  8. Hero = nil  
  9. oneHero:skill(30)  
  10. print(oneHero.attack) --> 130  

请注意上面 :  的使用,冒号可以在方法中添加一个额外的隐藏参数。 上面其实也看到了Hero.skill() 和Hero:skill()的区别。


二、类,将table作为自己的元表
例如上面的Hero例子,我们修改下:
[cpp]  view plain copy
  1. Hero = {}  
  2.   
  3. function Hero:new(o)  
  4.   o = o or {}  
  5.   setmetatable(o,self)  
  6.   self.__index = self  
  7.   return o  
  8. end  
  9.   
  10. function Hero:skill(addAttack)  
  11.   self.attack = self.attack + addAttack  
  12. end  
  13.   
  14. oneHero = Hero:new{attack = 90}  
  15. oneHero:skill(10)  
  16. print(oneHero.attack) -->100  

创建一个新英雄的时候,oneHero将Hero设置为自己的元表,当oneHero:skill(10)的时候,在table oneHero中查找skill,没有找到后,会进一步搜索元表的__index。


所以等价于:getmetatable(oneHero).__index.skill(oneHero,10)


而getmetatable(oneHero) 是Hero,Hero.__index还是Hero


所以等价于Hero.skill(oneHero,10)




三、继承
例如:
[cpp]  view plain copy
  1. Hero = {attack = 0}  
  2.    
  3.  function Hero:new(o)  
  4.    o = o or {}  
  5.    setmetatable(o,self)  
  6.    self.__index = self  
  7.    return o  
  8.  end  
  9.    
  10.  function Hero:skill(addAttack)  
  11.    self.attack = self.attack + addAttack  
  12.  end  
  13.    
  14.  function Hero:injured(loseAttack)  
  15.    if loseAttack > self.attack then error"not engouth attack" end  
  16.    self.attack = self.attack - loseAttack  
  17.  end  
  18.    
  19.  HumanHero = Hero:new()  
  20.    
  21.  oneHero = HumanHero:new{attack = 100}  
  22.  oneHero:skill(10)  
  23.    
  24.  print(oneHero.attack) -->110  

每个对象没有的方法都会去父类中查找(这里理解为父类),所以如果某个对象需要一些新的属性方法,只需要在该对象中实现就可以了。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值