撰写于 2018-05-25
<span id="post-title-updated">修改于 2018-05-25</span>
<span id="post-title-categories">分类
<a href="/categories/高级Lua/">高级Lua</a>
</span>
<span id="post-title-tags">
标签
<a href="/tags/Lua/">Lua</a>
</span>
</p>
<p>lua本身是不具有OO的特性,但是里面有一些特殊性东西可以帮助lua实现OO,例如可以巧妙的使用metatable,实现继承;lua的底层是<br/>C,本事是不支持多态,但是可以通过覆盖,实现简单的函数的多态。那封装是怎么实现的呢?</p>
lua的封装很简单,为了防止命名污染,工程里面一般使用的一个table,把自定义的函数和变量存入里面,这样就保证了这些变量和函数的名字有了独立的命名空间,大概如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| local P = {}
function (x) return tonumber(x) end
function P:new() local o = {} setmetatable(o, self) self._index = self return o end
function P:add(x, y) local x_num = self:toNumber(x) local y_num = self:toNumber(y) if x_num and y_num then return x_num + y_num end end
return P
|
如果我们不想让函数 toNumer “暴露”出去,只在内部使用,也就相当于OO的私有函数,怎么处理呢?很简单,不把 toNumber 放在 P 中就好了,这样函数就不会暴露出去。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| local P = {}
function toNumer(x) return tonumber(x) end
function P:new() local o = {} setmetatable(o, self) self._index = self return o end
function P:add(x, y) local x_num = self:toNumber(x) local y_num = self:toNumber(y) if x_num and y_num then return x_num + y_num end end
return P
|
还有一种方法,就是把所有的函数都定义为局部函数,把需要暴露出去的函数放入table中,这样我们不再需要调用函数的时候在前面加上前缀,公有的和私有的函数调用方法相同。在package的结尾处,有一个简单的列表列出所有公有的函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| function toNumer(x) return tonumber(x) end
function new() local o = {} setmetatable(o, self) self._index = self return o end
function add(x, y) local x_num = self:toNumber(x) local y_num = self:toNumber(y) if x_num and y_num then return x_num + y_num end end
return {new = new, add = add}
|
参考文献:lua手册