使用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, )
-- 呼叫初始化方法
dolocal
create
create = function(c, ...)
if c.super then
create(c.super, ...)
endif c.__init then
c.__init(obj, ...)
endend
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)
endnow_super = now_super.super
endend
return obj
endlocal vtbl = {}
_class[class_type] = vtbl
setmetatable(class_type, )
if super then
setmetatable(vtbl, )
endreturn class_type
end
--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
()end
a = nil
a = son:new()
a:play()
a:bind()
console:
father:init
son:init
father:play
son:bind
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
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,直接找到了函式,然後呼叫。
小結:
看著是有點亂,但是你多看幾遍,你就會有所收穫。
這個**可以說,我們在開發遊戲的時候,使用的base**。
0基礎lua學習(十三)Metatable
在 lua table 中我們可以訪問對應的key來得到value值,但是卻無法對兩個 table 進行操作。因此 lua 提供了元表 metatable 允許我們改變table的行為,每個行為關聯了對應的元方法。mytable 普通表 mymetatable 元表 setmetatable myt...
Lua基礎學習 Lua函式
函式主要用途 1 是作為呼叫語句使用。2 作為賦值語句的表示式使用。語法 區域性 全域性 function fun name 引數列表 函式體endfunction 定義函式關鍵字注意 1 在使用 lua 函式 變數時一定要先定義函式 變數 2 lua 函式不支援引數預設值,可以使用 or 解決。如...
0基礎lua學習(六)控制語句
demo 省略了c語言的括號 if a b then else if a c then end lua中不支援switch case demo 定義變數 a 10 使用 if 語句 if a 20 then if 條件為true 時列印以下資訊 print a 小於 20 endprint a 的值...