Lua類的實現

2021-07-26 20:24:58 字數 3611 閱讀 1505

cocos2dx中有關於lua類的實現,見cocos原始碼 framework/functions。

先講一部分比較難理解的:

function class(classname, super)   

local cls

-- inherited from lua object

if super then

cls = {}

setmetatable(cls, )

cls.super = super

else

cls =

endcls.__cname = classname

cls.__ctype = 2 -- lua

cls.__index = cls

function cls.new(...)

local instance = setmetatable({}, cls)

instance.class = cls

instance:ctor(...)

return instance

endreturn cls

end

主要涉及lua的乙個用法——元表。通俗的講,假設a和b都是table,b裡面有鍵值對,裡面有b,a裡面沒有,想在a裡面找b會找不到,如果setmetatable(a,b),則會去看b,看b有沒有設定__index欄位,如果有就會去b裡面找鍵值對。

對於類來講,假設有類a,當呼叫例項的方法a時,發現找不到,因為雖然a中有方法,但是例項中沒有新增該方法,由於上面 local instance = setmetatable({}, cls),例項就會去檢視cls即類a,而通過cls.__index = cls,a有把自己設定為__index,查a的時候就會去查它本身所有的鍵值對,即它所有的成員,方法a就被找到了。

另一種情況,如果類a的例項想呼叫方法s,而s是在類a的基類類s中定義的,a中並沒有定義,由於a定義的時候有setmetatable(cls, ),則找方法s的時候會去找a的super,即s,且super設定了__index,也可被找到,繼承就實現了。

再講另外一部分:

if supertype == "function"

or (super

andsuper.__ctype == 1) then

這句是指如果 function class(classname, super) 裡的super是函式,或者是c++類,則進行不同於上面的處理(上面是指lua的類和繼承),**如下:

cls = {}

if supertype == "table" then

-- copy fields from super

for k,v in pairs(super) do cls[k] = v end

cls.__create = super.__create

cls.super = super

else

cls.__create = super

cls.ctor = function() end

endcls.__cname = classname

cls.__ctype = 1

function cls.new(...)

local instance = cls.__create(...)

-- copy fields from class to native object

for k,v in pairs(cls) do instance[k] = v end

instance.class = cls

instance:ctor(...)

return instance

end

其實這裡比較好理解了,如果繼承自table,需要把基類所有成員複製過來,如果super引數是個函式,則需要在函式中通過基類建立子類。而在cls.new(…)函式裡面,例項化時也要拷貝所有的成員,這樣父類的成員就可以為子類的例項所用了,cocos裡面找了兩個例子:

local uibutton = class("uibutton", function

() return display.newnode()

end)

local uibutton = import(".uibutton")

local uipushbutton = class("uipushbutton", uibutton)

附一下cocos注釋裡面提供的示例:

-- 定義名為 shape 的基礎類

local shape = class("shape")

-- ctor() 是類的建構函式,在呼叫 shape.new() 建立 shape 物件例項時會自動執行

function

shape:ctor(shapename)

self.shapename = shapename

printf("shape:ctor(%s)", self.shapename)

end-- 為 shape 定義個名為 draw() 的方法

function

shape:draw()

printf("draw %s", self.shapename)

end-- circle 是 shape 的繼承類

local circle = class("circle", shape)

function

circle:ctor()

-- 如果繼承類覆蓋了 ctor() 建構函式,那麼必須手動呼叫父類建構函式

-- 類名.super 可以訪問指定類的父類

circle.super.ctor(self, "circle")

self.radius = 100

endfunction

circle:setradius(radius)

self.radius = radius

end-- 覆蓋父類的同名方法

function

circle:draw()

printf("draw %s, raidus = %0.2f", self.shapename, self.raidus)

end--

local rectangle = class("rectangle", shape)

function

rectangle:ctor()

rectangle.super.ctor(self, "rectangle")

end--

local circle = circle.new() -- 輸出: shape:ctor(circle)

circle:setraidus(200)

circle:draw() -- 輸出: draw circle, radius = 200.00

local rectangle = rectangle.new() -- 輸出: shape:ctor(rectangle)

rectangle:draw() -- 輸出: draw rectangle

lua實現類的繼承

local class function class super local class type class type.ctor false class type.super super class type.new function local obj do 遞迴呼叫建構函式,實現構造基類的資料...

Lua的類Class實現

在lua的開頭檔案中宣告 module classa package.seeall 後面宣告函式 function test end則在其他lua檔案中只要require進本檔案,即可classa.test 使用。在lua的開頭檔案中宣告 classa 後面宣告函式 function classa....

lua 類的繼承實現

1.lua 類中其實沒有類的概念,乙個類只是用乙個表 table 來管理的,如果想要實現子類繼承父類,簡單來說就是把兩個表組到一起。2.lua中提供了原表 metatable 可以通過原表來改變原來lua類的一些行為,比如把兩個表相加 a b father classfather.index cla...