撰写于 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手册