Lua中实现面向对象的一种漂亮解决方案

时间:2021-05-22

在 pil 中,lua 的作者推荐了一种方案来实现 OO,比较简洁,但是我依然觉得有些繁琐。

这里给出一种更漂亮一点的解决方案,见下文:

这里提供 Lua 中实现 OO 的一种方案:
复制代码 代码如下:
local _class={}

function class(super)
local class_type={}
class_type.ctor=false
class_type.super=super
class_type.new=function(...)
local obj={}
do
local create
create = function(c,...)
if c.super then
create(c.super,...)
end
if c.ctor then
c.ctor(obj,...)
end
end

create(class_type,...)
end
setmetatable(obj,{ __index=_class[class_type] })
return obj
end
local vtbl={}
_class[class_type]=vtbl

setmetatable(class_type,{__newindex=
function(t,k,v)
vtbl[k]=v
end
})

if super then
setmetatable(vtbl,{__index=
function(t,k)
local ret=_class[super][k]
vtbl[k]=ret
return ret
end
})
end

return class_type
end

现在,我们来看看怎么使用:
base_type=class()-- 定义一个基类 base_type
复制代码 代码如下:
function base_type:ctor(x)-- 定义 base_type 的构造函数
print("base_type ctor")
self.x=x
end

function base_type:print_x()-- 定义一个成员函数 base_type:print_x
print(self.x)
end

function base_type:hello()-- 定义另一个成员函数 base_type:hello
print("hello base_type")
end

以上是基本的 class 定义的语法,完全兼容 lua 的编程习惯。我增加了一个叫做 ctor 的词,作为构造函数的名字。
下面看看怎样继承:
复制代码 代码如下:
test=class(base_type)-- 定义一个类 test 继承于 base_type

function test:ctor()-- 定义 test 的构造函数
print("test ctor")
end

function test:hello()-- 重载 base_type:hello 为 test:hello
print("hello test")
end

现在可以试一下了:
复制代码 代码如下:
a=test.new(1)-- 输出两行,base_type ctor 和 test ctor 。这个对象被正确的构造了。
a:print_x()-- 输出 1 ,这个是基类 base_type 中的成员函数。
a:hello()-- 输出 hello test ,这个函数被重载了。

在这个方案中,只定义了一个函数 class(super) ,用这个函数,我们就可以方便的在 lua 中定义类:
复制代码 代码如下:
base_type=class() -- 定义一个基类 base_type

function base_type:ctor(x) -- 定义 base_type 的构造函数
print("base_type ctor")
self.x=x
end

function base_type:print_x() -- 定义一个成员函数 base_type:print_x
print(self.x)
end

function base_type:hello() -- 定义另一个成员函数 base_type:hello
print("hello base_type")
end

以上是基本的 class 定义的语法,完全兼容 lua 的编程习惯。我增加了一个叫做 ctor 的词,作为构造函数的名字。

下面看看怎样继承: test=class(basetype) -- 定义一个类 test 继承于 basetype
复制代码 代码如下:
function test:ctor() -- 定义 test 的构造函数
print("test ctor")
end

function test:hello() -- 重载 base_type:hello 为 test:hello
print("hello test")
end

现在可以试一下了:
复制代码 代码如下:
a=test.new(1) -- 输出两行,base_type ctor 和 test ctor 。这个对象被正确的构造了。
a:print_x() -- 输出 1 ,这个是基类 base_type 中的成员函数。
a:hello() -- 输出 hello test ,这个函数被重载了。

其实,实现多重继承也并不复杂,这里就不再展开了。更有意义的扩展可能是增加一个 dtor :)

ps. 这里用了点小技巧,将 self 绑定到 closure 上,所以并不使用 a:hello 而是直接用 a.hello 调用成员函数。这个技巧并不非常有用,从效率角度上说,还是不用为好。

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章