cocos2d+lua绑定关系理解——class函数

class函数返回一个具有new函数和create函数的table。

调用class函数的时候可以传入function类型或table类型的参数,可以实现类似c++"继承"效果。

下面是class函数使用的两个示例

示例一

local MyLayer=class("MyLayer", function() 
    return cc.Layer:create()
end)
local layer = MyLayer:create()

“继承”自c++创建的userdata。

示例二

local FishBase = class("FishBase")
FishBase.Init = function()
    print("FishBase Init")
end

local BigShark = class("BigShark",FishBase)
BigShark.Init = function()
    print("BigShark Init")
end

local fish = BigShark:create()
fish.Init()

创建一个“继承”自FishBase的“子类”BigShark并且重写了其中的Init方法。

下面来看一下class函数的具体实现。

function class(classname, ...)
    --创建一张新表cls作为返回值
    local cls = {__cname = classname}

    --遍历传入的所有参数,
    local supers = {...}
    for _, super in ipairs(supers) do
        local superType = type(super)
        assert(superType == "nil" or superType == "table" or superType == "function",
            string.format("class() - create class \"%s\" with invalid super class type \"%s\"",
                classname, superType))

        if superType == "function" then
            assert(cls.__create == nil,
                string.format("class() - create class \"%s\" with more than one creating function",
                    classname));
            -- 如果传入参数是函数,设置__create为此函数
            cls.__create = super
        elseif superType == "table" then
            --如果传入参数是cocos绑定的table,例如cc.Sprite
            if super[".isclass"] then
                assert(cls.__create == nil,
                    string.format("class() - create class \"%s\" with more than one creating function or native class",
                        classname));
                --__create函数为table的create函数
                cls.__create = function() return super:create() end
            else
                --如果传入参数为普通的table,放入__supers表中
                cls.__supers = cls.__supers or {}
                cls.__supers[#cls.__supers + 1] = super
                if not cls.super then
                    -- set first super pure lua class as class.super
                    cls.super = super
                end
            end
        else
            error(string.format("class() - create class \"%s\" with invalid super type",
                        classname), 0)
        end
    end

    --cls将作为元表(metatable)使用
    cls.__index = cls
    if not cls.__supers or #cls.__supers == 1 then
        --在没有__supers或__supers长度为1的情况下,cls的元表的__index指向cls.super
        setmetatable(cls, {__index = cls.super})
    else
        --在__supers有多个的情况下__index为函数,函数在每个super中查找。
        setmetatable(cls, {__index = function(_, key)
            local supers = cls.__supers
            for i = 1, #supers do
                local super = supers[i]
                if super[key] then return super[key] end
            end
        end})
    end

    --检查并添加ctor函数
    if not cls.ctor then
        -- add default constructor
        cls.ctor = function() end
    end
    --创建new函数
    cls.new = function(...)
        local instance
        --如果有__create函数,调用__create函数,
        if cls.__create then
            instance = cls.__create(...)
        else
            instance = {}
        end
        --cls作为元表使用
        setmetatableindex(instance, cls)
        instance.class = cls
        --调用构造函数
        instance:ctor(...)
        return instance
    end
    cls.create = function(_, ...)
        return cls.new(...)
    end

    return cls
end

函数的核心思想在于运用元表(metatable)实现类似c++"继承"效果。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值