Cocos2d-x Lua游戏开发之Lua 面向对象编程

浅谈 LUA 的面向对象设计方法By Apache

对应于 Java C++中的对象,Lua 中的对象可以使用 table 创建。我们通过如下的方式创建一个简单的对象:
Cat = {age = 1}
function Cat.grow()

Cat.age = Cat.age + 1end

我们在创建函数时使用Cat.的形式将 grow 添加到 Cat 对象的域中。这样我们就可以在需要增加 Cat 年龄的时候使用 Cat.grow()的方式调用 Cat grow 方法。然而这样做却存在两个问题:

1.在函数中使用全局变量是一个不好的习惯。

2.grow 函数只有在其所属对象被存储在了特殊的变量中(所属对象名Cat 中)时才可以使用,因为我们在 grow 的实现中明确的使用 Cat.age 来使用 age 成员,而不像 Java 使用 this 来表示当前对象。

因此,如果使用下面的代码调用grow 函数就会出错:
c = Cat; Cat = nil
c.grow()
--发生错误,因为 grow 要求其所属对象名必须存储在Cat 中。这违背了对象应该具有独立的生命周期的原则(c 对象未被清除,但却已经失效)。解决的办

法是使用额外的特殊参数 self(就像 Java 中的 this)来表示方法作用的对象:Cat = {age = 1}

function Cat.grow(self)self.age = self.age + 1

end

此时使用下面的代码调用grow 函数则不会出错:
c = Cat; Cat = nil
c.grow(c)
--不会出错,因为我们已经明确的告知了grow 函数它需要作用的对象啦。这种写法虽然解决了以上的问题,却有些美中不足,它要求程序员必须显式的指明定义时的

self 形参与调用时的对象实参。常见于大部分OO 语言的做法是将这种机制进行隐藏,这样程序员就不必声明这个参数(仍然可以像声明过了一样的使用这个参数)。庆幸的是Lua 也提供了这种机制。因此我们得以使用如下的更简洁的代码:

Cat = {age = 1}function Cat:grow()

self.age = self.age + 1end

c=Catc:grow()--调用时也无需传入对象作为实参,但如果你喜欢仍可以使用c.grow(c)的方式调用。

以上介绍了使用 table 创建对象的方法,但上述的对象还没有类的继承特性。实际上Lua 并不存在像 Java C++那样清晰的类的概念,因为Lua 中的对象并非来自用于创建对象的模板。然而Lua 中存在原型的概念,Lua 中的对象都会有一个原型,当调用不属于对象的操作时,Lua 会到该对象的原型中查找这个操作。因此我们可以创建一个对象作为另一个对象的原型,来实现类的继承特性。实际上类和原型的工作机制是一致的,它们都是定义了特定对象的行为。

例如我们分别创建了 Animal Tiger 对象:


显然 Tiger 对象也具有 sizeage 属性和 sleepeat 方法,要让 Tiger 继承 Animal 的属性和方法,只需设置 Animal 对象为 Tiger 的原型:setmetatable(Tiger, (__index = Animal))。如图:


Animal 设置为 Tiger 的原型后再调用 Tiger 对象中不存在的方法,Lua 就会去 Tiger 的原型Animal 中查找该方法。术语上可将Animal 看做是类,但实际上这是一种基于Lua 原型特性的对象间的继承。我们还可以将setmetatable(Tiger,(__index= Animal))稍作修改后写成Animal的一个 new方法:



这样的做法更符合面向对象设计的习惯。另外在创建Cat 对象时没有提供初始化size age 的值,因此 Cat.size Cat.age 都为 nil。而 Bird.size Bird.age 分别为“small”和 1。还有一个有趣的现象是如果一个对象需要一个不同于原型中已定义的特殊的行为,则只需为这个对象设计单独的实现,就像 Java 中函数重写:


这是因为当调用 UnknownAnimal eat 方法时重写后的定义会被触发执行,Lua 不再查找原型中eat 方法。

除了以上的面向对象特性以外,Lua 还支持多重继承(实现比较复杂)和属性私有化(也不怎么常用,实际上如果你不需要访问对象内的一些属性,你就不要访问好了)。Lua 定位于中小型应用,因此不要指望它可以像Java 那样优秀的面向对象,也不要指望它像Python 那样无所不能。 


上述作者的lua的简单继承,对象的实现都比较好,所以根据c++使用习惯,我选择 :



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值