luaoop | 实现基本的OO 框架
Posted 自科部
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luaoop | 实现基本的OO 框架相关的知识,希望对你有一定的参考价值。
lua虽然原生面向对象,不过它提供了一些功能,使得我们很容易模拟出对象
云风以前也实现过一次,代码有点复杂,我想重新实现一些。
目标
实现一个Class 函数,它接收一个构造函数,然后返回一个生成器,每次调用这个生成器可以生成一个新的对象。
具体用法如下:
package.path=package.path..";./code/luagy/?.lua;./luagy/?.lua"
Class=require("grammar.class")
baseclass=Class(function (self,x) --构造函数
self.x=x
print ("baseclass init ")
self:fn(x)
end
)
baseclass.level=1 --属性
function baseclass:fn(x) --方法
print("call baseclass fn")
self.x=x
end
baseobj1=baseclass(1) --新建对象
baseobj2=baseclass(2)
print(baseobj1.x,baseobj2.x)
baseobj2:fn(3)
print(baseobj1.x,baseobj2.x)
baseobj1.level=3
print(baseclass.level,baseobj2.level,baseobj1.level)
实现
用了十多行实现了基本的功能:
local function Class( _ctor)
local c = {} --生成器
c.__index = c --对象要从类索引方法等
c._ctor = _ctor --保留构造函数
setmetatable(c, {__call = function(class_tbl, ...)
local obj = {} --新的对象
setmetatable(obj,c)
if c._ctor then
c._ctor(obj,...)
end
return obj
end})
return c
end
return Class
继承
下面来实现关于的类的继承
目标是实现类似下面的调用
childclass1=Class(baseclass,function (self,y)
self.y=y
end)
co1=childclass1(3)
co1:fn(2)
print(co1.x,co1.y,co1.level)
只要把Class 函数的参数改成两个,如果第一个参数类型是函数的话,说明它是一个基类,不用从父类复制方法和属性,相反,如果是table,就复制父类的所有属性的方法到子类,然后用第二个参数构造生成器。
这也就是为什么Class返回的是table而不是函数的原因之一
具体如下:
local function Class(base, _ctor)
local c = {} --生成器
if not _ctor and type(base) == 'function' then
--基类
_ctor = base
base = nil
elseif type(base) == 'table' then
--复制父类的方法
for i,v in pairs(base) do
c[i] = v
end
c._base = base
end
c.__index = c --对象要从类索引方法等
c._ctor = _ctor --保留构造函数
setmetatable(c, {__call = function(class_tbl, ...)
local obj = {} --新的对象
setmetatable(obj,c)
if c._ctor then
c._ctor(obj,...)
end
return obj
end})
return c
end
return Class
这样一个基本的 OO框架就完成了,不过还有许多的问题。首先,在从父类复制属性时,是利用浅复制,假如属性的类型是table,修改子类的该属性,父类的也会跟着改变。或者可以这样解决:
对于特殊的类型(如table) 递归复制,直到所有变量都为基本类型为止,但是有些类型(userdata)并不能进行深复制,要有对应的复制函数
将属性的定义放在一个特殊的函数里,每次构造新对象重新生成属性,这样的代码基本上不用改动,问题就得到解决
由于每一次新建一个类时,父类的构造函数被重载了,所以要调用父类的构造函数只能这样
cc2=Class(baseclass,function (self)
self._base._ctor(self)
...
end)
还有,因为使用了元表,但是lua的实现中元表是不能无限嵌套的(防止无限递归)所以下面的代码会出错
以上是关于luaoop | 实现基本的OO 框架的主要内容,如果未能解决你的问题,请参考以下文章