0基础lua学习(十六)lua的多态 base
来源:互联网 发布:ubuntu win7双系统安装 编辑:程序博客网 时间:2024/06/04 08:26
多态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_typeend
--main.lua代码require"base"father = father or BaseClass()function father:__init() print("father:init")endfunction father:Bind() print("father:Bind")endfunction father:play() print("father:play")endson = son or BaseClass(father)function son:__init() print("son:init")endfunction son:Bind() print("son:Bind")endfunction son:UnBind()enda = nila = 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 retend
_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基础lua学习(十六)lua的多态 base
- 0基础lua学习(十二)Lua 模块与包
- 0基础lua学习(二十)Lua单例
- 0基础lua学习(十八)C调用Lua----02Lua堆栈
- 0基础lua学习(十九)C调用Lua----03C调用lua 函数和变量
- 0基础lua学习(一)HelloWorld
- 0基础lua学习(二) 数据类型
- 0基础lua学习(七)函数
- 0基础lua学习(八)字符串
- 0基础lua学习(九)数组
- 0基础lua学习(十)迭代器
- 0基础lua学习(十一)table
- 0基础lua学习(十三)Metatable
- 0基础lua学习(十四)封装
- lua学习笔记(1) --Lua基础语法
- Lua基础点学习
- Lua基础学习(一)
- Lua基础 函数学习
- 小白学习Hibernate遇到的错误以及解决办法(GenerationTarget encountered exception accepting command : Error executing)
- Implementing a CNN for Human Activity Recognition in Tensorflow
- 改进排序算法:归并排序
- 用链表+函数指针+定时器中断实现的一个软件定时器(试用于所有单片机)
- oKhttp第三方登录
- 0基础lua学习(十六)lua的多态 base
- Vim 命令行快捷键
- 对list里的数据进行大小的排序
- Mac+windows下excel转化为复杂的json格式,将xlsx文件转成json(可内嵌对象数组)
- 慕课网《HTML+CSS基础课程》笔记总结(一)
- 选择恐惧症的福音!教你认清MVC,MVP和MVVM
- 共享时代的新宠儿自动售菜机
- 数据排序:冒泡排序
- Centos 与本地终端 上传、下载 文件