事实上lua对于oop并没有语言上的支持(也即没有class之类的关键字),但是我们却可以利用lua本身来实现一些类似oop的效果,基本思路上有两种,基于table和基于closure的,以下是两种方案的一个大致比较
+---------------------------------------+---------------------------+-------------------------------------------------+
| Subject | Tables approach | Closured approach |
+---------------------------------------+---------------------------+-------------------------------------------------+
| Speed test results | 47 sec. | 38 sec. |
| Memory usage test results | 48433 Kbytes | 60932 Kbytes |
| Methods declaration form | Messy | More clean |
| Private methods | Fine | Fine |
| Public methods | Fine | Fine |
| Private variables | Not available | Fine |
| Public variables | Fine | Fine |
| Polymorphism | Fine | Fine |
| Function overriding | Ugly (namespace flooding) | Fine (if we grant access only to direct parent) |
| Whole class definition (at my taste) | Pretty messy | Kinda clean |
+---------------------------------------+---------------------------+-------------------------------------------------+
结论来源于 http://lua-users.org/wiki/ObjectOrientationClosureApproach
从上面的比较中,我们可以看到,除了内存使用一项外,closure方案完胜,因此我们主要来看一下基于closure的实现方案
首先我们来看两个c++的类
class CBase
{
private:
CBase();
virtual ~CBase();
public:
static CBase* create();
void publicMethod();
static void publicStaticMethod();
virtual void virtualMethod();
private:
void privateMethod();
static void privateStaticMethod();
public:
static int mPublicStaticVar;
int mPublicVar;
private:
int mPrivateVar;
static int mPrivateStaticVar;
};
class CDerived: public CBase
{
public:
static CDerived* create();
virtual void virtualMethod();
};
要实现这两个类,我们从lua的closure方式如何实现呢?
Base.lua
module("Base", package.seeall)
mPublicStaticVar = 1
local mPrivateStaticVar = 2
local function privateStaticMethod()
print("privateStaticMethod called")
end
function publicStaticMethod()
print("publicStaticMethod called")
end
function create()
local self = {
mPublicVar = 3,
}
local mPrivateVar = 4
local function privateMethod()
print("privateMethod called")
end
function self.publicMethod()
print("publicMethod called")
end
function self.virtualMethod()
print("virtual Method called from Base")
end
return self
end
Derived.lua
module("Derived", package.seeall)
require("example.Base")
function create()
local self = Base.create()
local baseVirtualMethod = self.virtualMethod
function self.virtualMethod()
baseVirtualMethod()
print("virtualMethod called from Derived")
end
return self
end
测试代码
require("example.Derived")
Base.mPublicStaticVar = 1
Base.publicStaticMethod()
local base = Base.create()
base.virtualMethod()
base.publicMethod()
base.mPublicVar = 3
print(base.mPublicVar)
local derived = Derived.create()
derived.virtualMethod()
derived.publicMethod()
derived.mPublicVar = 4
print(derived.mPublicVar)
相信大家都能看得懂这个代码,简单清爽。