lua是一门简单的语言,不带类和属性封装,但可以使用lua强大的元表模拟实现:
class.lua
local type = type local rawset = rawset local setmetatable = setmetatable local traceCount = 0 local tracebacks = setmetatable({}, {__mode = "k"}) local function class(classname, super) local cls = {} cls.classname = classname cls.class = cls cls.Get = {} cls.Set = {} local Get = cls.Get local Set = cls.Set if super then -- copy super method for key, value in pairs(super) do if type(value) == "function" and key ~= "ctor" then cls[key] = value end end -- copy super getter for key, value in pairs(super.Get) do Get[key] = value end -- copy super setter for key, value in pairs(super.Set) do Set[key] = value end cls.super = super end function cls.__index(self, key) local func = cls[key] if func then return func end local getter = Get[key] if getter then return getter(self) end return nil end function cls.__newindex(self, key, value) local setter = Set[key] if setter then setter(self, value or false) return end if Get[key] then assert(false, "readonly property") end rawset(self, key, value) end function cls.new(...) local self = setmetatable({}, cls) local function create(cls, ...) if cls.super then create(cls.super, ...) end if cls.ctor then cls.ctor(self, ...) end end create(cls, ...) -- debug traceCount = traceCount + 1 tracebacks[self] = traceCount return self end return cls end return class
示例:
local class = require "class" local Point = class("Point") function Point:ctor(x, y) self.x = x self.y = y end function Point.Get:x() return self._x end function Point.Set:x(value) self._x = value end function Point.Get:y() return self._y end function Point.Set:y(value) self._y = value end local p = Point.new(10, 20) print(p.x, p.y) p.x = 5 p.y = 5 print(p.x, p.y)
local class = require "class" local Sprite = class("Sprite") function Sprite:ctor() self.cobj = cc.Sprite:create() end function Sprite.Get:x() return self.cobj:getPositionX() end function Sprite.Set:x(value) self.cobj:setPositionX(value) end function Sprite.Get:y() return self.cobj:getPositionY() end function Sprite.Set:y(value) self.cobj:setPositionY(value) end local obj = Sprite.new() obj.x = 30 obj.y = 40 obj.y = obj.x
这样做的好处就是,可以比较自然的访问和赋值一些变量,特别是UI布局中,可以少写很多setXX、getXX的方法。