• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

理解LUA中的多重继承

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

有人在问如何实现Lua中的多重继承。真正用到多重继承的时候,我会想想是不是非得用多重继承,总觉得多重继承有点“重”。

 

 

多重继承例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
local function search(k, tables)
    for i, v in ipairs(tables) do
        if v[k] then
            return v[k]
        end
    end
    return nil
end
 
-- 这里实现多重继承,参数arg为多重父类表
 
function createClassFrom(...)
    -- c为返回值的目标表,为实现多重继承的子类表
 
    local c = {}  
    local parents = {...}
    setmetatable(c, {__index = function(t, k)
        return search(k, parents)
    end})
 
    function c:new(o)
        o = o or {}
        setmetatable(o, {__index = c})
        return o
    end
 
    return c
end
 
-- 人 吃饭
 
Human = {name = "human"}
function Human:eat()
    print("human eat")
end
 
-- 程序员 写代码
 
Programmer = {name = "coder"}
function Programmer:doProgramming()
    print("do coding")
end
 
-- 女程序员 继承 人和程序员
 
-- 性别女
 
FemaleProgrammer = createClassFrom(Human, Programmer)
local femaleCoder = FemaleProgrammer:new({sex = "female", canBear = function() print("Female: can give birth a baby!") end})
femaleCoder:eat() -- human eat
 
femaleCoder:doProgramming() -- do coding

 

 

上面代码难点在于理解lua中__index的用法。我们在lua中实现继承的时候,会用到这个__index。我们再次看看这个__index究竟是怎么回事。元表的__index可以是一个表,也可以是一个函数。

 

 

1. __index是个表的情况

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
local Test = { group = "quick" }
function Test:new(o)
    o = o or {}
    setmetatable(o, {__index = Test})
    return o
end
 
function Test:getName()
    return self.name
end
 
function Test:setName(name)
    self.name = name
end
 
local a = Test:new({name = "Just a test"})
print(a:getName()) -- Just a test
 
print(a.group) -- quick

 

 

当表a调用自身所没有的方法( getName() )或者属性(group)的时候, Lua会通过getmetatable(a)得到a的元表{index = Test}, 而该元表的`index`是个表Test,则Lua会在这个表Test中看看是否有缺少的域方法("getName")以及属性(group),如果找到了则会调用表Test的方法或者属性。

 

2. __index 是函数的情况

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
local Test = { }
Test.prototype = { group = "quick",
                   qq = "284148017",
                   company = "chukong",
                   getName = function() return "Just a test" end}
 
function Test:new(o)
    o = o or {}
    setmetatable(o, {__index = function(table, key)
        return Test.prototype[key]
    end})
    return o
end
 
local a = Test:new()
print(a:getName()) -- Just a test
 
print(a.qq) -- 284148017
 
print(a.company) -- chukong

 

 

当表a调用自身所没有的方法(getName)或者属性(qq/company)的时候, lua会通过getmetatable(a)得到a的元表
{__index = function(table, key) return Test.prototype[key] end}, 而该元表的__index是个函数,该函数的实参依次为正在调用方法、属性的表a以及表a中缺失的方法名或属性(键值key),lua会将这两个实参传入进去并调用__index指向的函数。

例如:

  • a:getName()时,就会调用a的元表的__index方法,将自身a以及"getName"键名依次传入进去,返回了Test.prototype["getName"]该函数,lua会自动调用该函数,所以a:getName()会返回Just a test。
  • a.qq时,就会调用a的元表的__index方法,将自身a以及"qq"键名依次传入进去,返回了Test.prototype["qq"]即284148017。

相关阅读


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
lua使用io.open跨平台文件夹遍历匹配查找发布时间:2022-07-22
下一篇:
centos7给已经安装nginx的添加lua模块发布时间:2022-07-22
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap