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
作者:半山
出处:http://www.cnblogs.com/xdao/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。