0基礎lua學習(十六)lua的多型 base

2021-08-10 12:54:39 字數 3510 閱讀 9576

使用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 的值...