Lua的面向对象写法

1.唠叨两句

最近闲的没事玩 暗黑2 怀旧. 哈哈哈哈哈哈 .需要开8个游戏一起操作,没有工具太麻烦了.于是产生了写个辅助工具的想法.
工具需求当然要求小巧可爱 开发方便.又容易修改.所以选了c#和lua相互配合.机缘巧合vs商店找到一个库neolua.找到了用了一下确实不错就开工了.
工具写好了.返回来发现blog里面也没有好好说过lua的一些东西.就突然又想写个文章来说说lua的一些东西.

1.Lua面向对象

Lua没有提供语法糖来干这个事情,所以要我们自己来.
首先说一下需要的知识点

1.1 matetable

这个翻译过来叫元表.为什么需要这个东西?原因在于面向对象需要继承这个功能.也就说你要找东西,当前的类没有,就会去找父类的东西.元表有一个__index这个东西.它有个内定的功能就是当 A有一个元表B. 并且 A的__index是B, 就会形成一个类似继承的关系.B有一个成员a, 那么A.a就会 跑去找到B.a.

1.2 lua的:语法

这个语法糖用来实现面向对象看起来会舒服很多.他会隐式的在函数里加入self.这个self就是调用者的引用.如果是.语法就写起来很麻烦了

1.3 比较舒服的面向对象写法

由于没有class这种语法糖 所以lua写肯定会有点别扭,但是没办法.这里我写了一个很简单的实例

1.4 setmetatable

这个函数需要两个参数 第一个是新table,第二个是元表,返回值是拥有元表的新table.就是第一个参数的table.查看内存地址,是同一个地址

2 代码实例

下面的代码有详细的注释:

CA = {} --CA类 说白了就是一个table

-- CA类的New, :的作用就是隐式的包含了self这个变量在函数里.self就是CA
-- 如果用.语法当然也可以就是多写几个字比较累看起来也不爽
function CA:new () 
    self.__index = self -- 元表需要的东西 __index作用在于如果当前的table没有的变量会到__index对应的table里面找东西

    self.a = "a" --自定义的变量
    self.b = "b"

    --设置元表 元表的作用在于让__index元方法生效,当你访问table,如果table里没有你要的变量,那么就会跑到index里面找.找到了就会调用.
    --这里的写法作用在于让新{}拥有CA这个元表, self就是CA,CA就是一个table,
    --这里也就实现了一个功能: 也就说当我们用新实例调用a这个变量,这个新实例你取到的是{},什么都没有,但是这个{}有一个元表就是CA,当我们
    --要取a变量的值,实际上会找__index发现值是CA.CA这个table里面有a 所以就取到了
    return setmetatable({}, self)
end

-- 声明一个成员函数Do
function CA:Do()
    print("CA:Do a=" .. self.a)
end

-- CB是一个继承CA的类.这里相当于实例化了一个新{}给CB,这个{}带有一个元表CA
CB = CA:new()
function CB:new()
    -- 同理,self就是CB 现在相当于 CB的__index = CB, CB包含CA的实例, CA的__index = CA,
    -- 所以你用CB的实例调用变量,会往上找.
    self.__index = self

    self.b = "CB b"

    -- 同理
    return setmetatable({}, self)
end

-- 声明一个成员函数Do
function CB:Do()
    print("CB:Do a=" .. self.a)
end

--实际上就是个空table但是有个元表CA
testA = CA:new() --实例化一个CA

-- 这个操作实际上是给{} 加了a.并不是改了CA.a. 所以不会影响到下面的CB.self就是CA
-- getmetatable(testA).__index.a = 111 或者 CA.a = 2222 --这样才会影响到CB.因为你修改了CA的a值啊. CA就是一个table
-- 也就说你这一步操作,会让testA实际上有两个a变量一个在自己身上,一个在元表CA上面,注意CA只是一个table.
testA.a = 100

--实际上就是个空table,但是这个空的table有个元表,这个元表的__index指向一个空table
-- 这个空table的__index指向CA, 所以没有的东西,最后都会找到CA头上去
testB = CB:new() --实例化一个CB

--这里肯定是打印出来100,原因很简单testA:Do, 这里self就是新的{}. 上面a=100了当然打印出来100
testA:Do() --CA:Do a=100

--上面说的了testB的table关系,全程没有找到a,最后肯定会找到CA头上 所以是a
testB:Do() --CB:Do a=a

--这里当然是100,因为给新的testA 设置了一个100
print(testA.a) --100

--这里testB是空的{}, 所以会去找元表, 当前元表是CA:new()出来的 __index就是这个CA:new(),
-- 实际上这时候也是空的没有a,但是元表是CA,所以继续找, 这时候也没有a
print(testB.a) -- a

3 尾声

下一篇 说一下暗黑2多开工具的具体需求和C#的neolua的用法.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值