lua--面向对象使用middleclass

昨天本来还想写一篇love2d之角色移动的,可是不知怎么回事,

我在一个类里有setXY(),在love.load()里调用了,可是居然没

按我的预想坐标,而是直接显示在了顶点.后来各种print,发现

确实是调用了,但就是不显示,郁闷,只好作罢.

后来也想不出原因,于是又看了一下lua面向对象,想到以后可能

很多地方会用到类,便想找一个简洁的lua面向对象的扩展.先推荐一个很好的lua博客,当lua语法不懂时,我常去翻阅.

到http://lua-users.org翻了一下,发现了一些面向对象的扩展,最终选择

了middleclass.middle意为中等,表明其是中等规模的

面向对象实现(作者介绍的),官网为https://github.com/kikito/middleclass/

不到140行代码就实现了,类,继承,虚函数,私有变量等.(下面的示例已带middleclass,可以不用下载)

作者也提到了没有实现的有

  • metaclasses   元类吗?不知道
  • classes are not Objects (instances are) 类的实例是Objects,而类不是
  • simulating a ‘super’ keyword (for performance concerns) 因为效率,没有模拟'super'关键字

根据作者的提示,简单的看看middleclass源码,发现在下面摘录的片断里第4步才setmetatable(),即在class的实例new()之后,

才把其绑定到Object上.(只是简单的看了一下,不确定正否,希望漂过的高手指正)

--1步
function
class(name, super, ...) super = super or Object return super:subclass(name, ...) end
--2
function Object.static:subclass(name)
  assert(_classes[self], "Make sure that you are using 'Class:subclass' instead of 'Class.subclass'")
  assert(type(name) == "string", "You must provide a name(string) for your class")

  local subclass = _createClass(name, self)
  _setClassMetamethods(subclass)
  _setDefaultInitializeMethod(subclass, self)
  self.subclasses[subclass] = true
  self:subclassed(subclass)

  return subclass
end
--3
function Object.static:new(...)
  local instance = self:allocate()
  instance:initialize(...)
  return instance
end
--4
function Object.static:allocate()
  assert(_classes[self], "Make sure that you are using 'Class:allocate' instead of 'Class.allocate'")
  return setmetatable({ class = self }, self.__instanceDict)
end

下面我们来使用middleclass,看其带来的方便之处(以下的内容来自官方文档,

英语好的同学可以自己去看).只介绍类和继承,其它的功能现在还用不上,等以后

再说.

test.lua

require 'middleclass'
--声明一个类,也可用class('Person', Object) 或Object:subclass('Person') middleclass的根类是Object
Person = class('Person')

--构造函数
function Person:initialize(name)
    self.name = name
end
function Person:speak()
    print('Hi, I am ' .. self.name ..'.')
end

--继承或Person:subclass('AgedPerson')
AgedPerson = class('AgedPerson', Person)
--类变量
AgedPerson.static.ADULT_AGE = 18

--注意在子类里要调用父类里的构造函数
function AgedPerson:initialize(name, age)
    Person.initialize(self, name) --注意在子类里要调用父类里的构造函数
    self.age = age
end

--覆盖子类里的方法,感觉确实像从c++里的虚函数
function AgedPerson:speak()
    Person.speak(self)
    --可以实例里直接访问类变量
    if(self.age < AgedPerson.ADULT_AGE) then
        print('I am a child.')
        else
        print('I am an adult.')
    end
end

--等价于AgedPerson('Billy the Kid', 13),new()隐含调用
local p1 = AgedPerson:new('Billy', 13)
local p2 = AgedPerson:new('Luke', 21)

p1:speak()
print("----------------")
p2:speak()

代码,已clone的直接git pull
git clone git://gitcafe.com/dwdcth/love2d-tutor.git
或git clone https://github.com/dwdcth/mylove2d-tutor-in-chinese.git

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值