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

0基础lua学习(十六)lua的多态base

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

使用lua实现C++类似的多态,看起来略微难了一些,这个demo,默认提供了 init类似构造函数的时机。

--base.lua代码
--保存类类型的虚表
local _class = {}
function BaseClass(super)
    -- 生成一个类类型
    local class_type = {}
    -- 在创建对象的时候自动调用
    class_type.__init = false
    class_type.__delete = false
    class_type.super = super
    class_type.New = function(...)

        -- 生成一个类对象
        local obj = {}
        obj._class_type = class_type

        -- 在初始化之前注册基类方法
        setmetatable(obj, { __index = _class[class_type] })

        -- 调用初始化方法
        do
            local create
            create = function(c, ...)
                if c.super then
                    create(c.super, ...)
                end
                if c.__init then
                    c.__init(obj, ...)
                end
            end

            create(class_type, ...)
        end

        -- 注册一个delete方法
        obj.DeleteMe = function(self)
            local now_super = self._class_type
            while now_super ~= nil do
                if now_super.__delete then
                    now_super.__delete(self)
                end
                now_super = now_super.super
            end
        end

        return obj
    end

    local vtbl = {}
    _class[class_type] = vtbl

    setmetatable(class_type, {__newindex =
    --table key value
        function(t,k,v)
            vtbl[k] = v
        end
        ,
        __index = vtbl, --For call parent method
    })

    if super then
        setmetatable(vtbl, {__index =
            function(t,k)
                local ret = _class[super][k]

                return ret
            end
        })
    end

    return class_type
end
--main.lua代码
require"base"

father = father or BaseClass()
function father:__init()
    print("father:init")
end

function father:Bind()
    print("father:Bind")
end

function father:play()
    print("father:play")
end


son = son or BaseClass(father)

function son:__init()
    print("son:init")
end

function son:Bind()
    print("son:Bind")
end

function son:UnBind()

end


a = nil
a = son:New()
a:play()
a:Bind()

console:
father:init
son:init
father:play
son:Bind

多态base解析

1.首先要明确
father = father or BaseClass( )和 son = son or BaseClass(father)
有一个共同的表local _class = {},也就是虚表。

2.father = father or BaseClass(),我们会保存__class[class_type] = vtbl
classtype是key,value是表
返回的表是 class_type

                vtbl
                 {__newindex =
                    function(t,k,v)   
                        vtbl[k] = v
                    end,
                  __index = vtbl
                 }

3.function father:__init(),会将class_type表中的__init 从布尔,变为函数
4.function father:Bind(),没有Bind函数,所以会调用vtbl表中的__newindex,因为我们没有Bind的key

    function(t,k,v)   
        vtbl[k] = v
    end

这样vtbl中添加了一个Bind的key,value是函数
5.son = son or BaseClass(father)同理,但是它的vtbl会添加__index = function(t,k)的函数

6.function son:__init(),会将class_type表中的__init 从布尔,变为函数
7.function son:Bind(),所以会调用

    function(t,k,v)   
        vtbl[k] = v
    end

向son的vtbl表中加入函数
8.a = son:New()这是
son = son or BaseClass(father)里面的new方法,调用父类的init,然后调用子类的init,然后返回
_class[class_type],这个是son的vtbl表。(_class里面有两个vtbl,key分别是father的class_type和son的class_type,其值是各自的vtbl表)

9.a:play()这是调用父类的play方法,首先去son的vtbl表中查找,通过__index调用了

function(t,k)
 local ret = _class[super][k]
 return ret
end

_class[super]这是访问虚表中的,father的vtbl,然后我们找到了,然后进行调用。
注意:如果我们换成a:play1(),就会报错all method ‘play1’ (a nil value) ,也就是你声明函数,要加到父类的表里
也就是下面这步

function father:play()
    print("father:play")
end

10.a:Bind(),其实就是找son的vtbl,直接找到了函数,然后调用。

小结:

  • 我们声明的 son继承 father之前,需要创建两个表,每个表里都有一个vtbl , 有一个总表_class来管理
  • __newindex 实现的是,我们创建函数添加函数,加到vtbl 表里
  • __index 实现的是,继承的实现。即访问父类里面的函数,如果子类实现了,就访问子类的。
  • t 是table、k是key、v是value

看着是有点乱,但是你多看几遍,你就会有所收获。
这个代码可以说,我们在开发游戏的时候,使用的base代码。


鲜花

握手

雷人

路过

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

请发表评论

全部评论

专题导读
上一篇:
openresty+lua+kafka实现日志收集发布时间:2022-07-22
下一篇:
(一)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