1. 程式人生 > >cocos2d-x lua中class的定義

cocos2d-x lua中class的定義

在lua中要實現對類的定義一般都是通過metatable來做到的。。例如:

Fjs = {}

function Fjs:new(name)
	local out = {}
	setmetatable(out, self)
	self.__index = self
	out.name = name
	return out
end


function Fjs:sayHello()
	print("my name is " .. self.name)
	print("hello")
end

local fjs = Fjs:new("fjs")
fjs:sayHello()


首先定義了一個table,然後在它上面定義相應的方法,在建立物件的時候,通過將物件的metatable指定為剛剛定義的table,這樣也就實現了方法的繫結。。也就實現了類的定義和物件的建立。

上述實現中,自己需要定義一些約定的程式碼,在cocos2d-x中,為了實現的方便,擴充套件了一個class方法用於實現定義型別,對於上述型別的定義可以簡化為如下:

Fjs = class("Fjs")

function Fjs:ctor(name)
	self.name = name
end

function Fjs:sayHello()
	print("I am " .. self.name)
	print("hello")
end

fjs = Fjs.new("fjs")
fjs:sayHello()

這個樣子看起來簡潔多了。。。這裡定義了一個ctor方法,這個是建構函式

為了理解class究竟是怎麼定義的。。來看看該方法的程式碼:

function class(classname, super)
    local superType = type(super)
    local cls

    --如果提供的super既不是函式,也不是table,那麼就直接將super當做不存在
    if superType ~= "function" and superType ~= "table" then
        superType = nil
        super = nil
    end

    --如果有提供super
    if superType == "function" or (super and super.__ctype == 1) then
        -- 定義一個table,它將作為類的定義
        cls = {}

        --如果super是table,那麼將super中定義的欄位先全部拷貝到cls中
        --然後將__create方法指定為super的__create方法
        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 
        --這裡提供的super時函式,那麼也就是用這個方法來構造物件,那麼直接將__create方法指向super
            cls.__create = super
        end

        --提供一個空的ctor建構函式
        cls.ctor    = function() end
        cls.__cname = classname
        cls.__ctype = 1

        --定義.new(...)方法,他使用者構建物件,首先是呼叫__create方法來構建一個table物件,然後將cls裡面定義的欄位全部拷貝到建立的物件中
        --接下來在呼叫ctor構造方法
        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

    else
        --從lua的型別中繼承
        if super then
            cls = clone(super)
            cls.super = super
        else
       	--直接就沒有super,那麼定義cls為一個帶有空ctor的table
            cls = {ctor = function() end}
        end

        cls.__cname = classname
        cls.__ctype = 2 -- lua
        cls.__index = cls

        --這裡的new方法,首先是建立了空的table,然後將其metatable指向為cls
        --然後在呼叫ctor構造方法
        function cls.new(...)
            local instance = setmetatable({}, cls)
            instance.class = cls
            instance:ctor(...)
            return instance
        end
    end
    --返回型別的定義
    return cls
end


註釋已經說的很明白了吧,我們接下來來分析一段常用的使用方式:

GameScene = class("GameScene", function()
	return cc.Scene:create()
end)

function GameScene:ctor()

end

function GameScene:create()
	return GameScene.new()
end


這是比較常用的自定義Scene的方法,提供了create方法來具體的構建GameScene物件。。

通過上述class的程式碼,我們可以知道如下的執行步驟:

(1)首先用class中定義的super函式來構建了一個物件,也就是Scene:create()之後得到的scene物件

(2)在該物件上呼叫定義的ctor方法

至於別的型別的定義,通過class程式碼的分析也能很容易的知道執行步驟