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

多态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:

多态base解析

1.首先要明确

2.father = father or BaseClass(),我们会保存__class[class_type] = vtbl

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

3.function father:__init(),会将class_type表中的__init 从布尔,变为函数

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

这样vtbl中添加了一个Bind的key,value是函数

6.function son:__init(),会将class_type表中的__init 从布尔,变为函数

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

向son的vtbl表中加入函数

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

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

_class[super]这是访问虚表中的,father的vtbl,然后我们找到了,然后进行调用。

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

看着是有点乱,但是你多看几遍,你就会有所收获。