Lua現實類 繼承 多繼承 階梯式繼承 多態

1.Lua類的實現–官方做法

原理1:lua通過表(table)實現類的結構
原理2:lua在通過元表的方式實現繼承

--定義父類obj
obj = {id = 0} --定義一個元素id

--通過new方法創建對象
function obj:new(o)
    o = o or {} 
    setmetatable(o,self) --設置obj是o的原表
    self.__index = self  --設置查找元方法
    -- 對象o調用不存在的成員時都會去self(obj)中查找,而這裏的self指的就是Object
	return o
end
function obj:Add()
	return 1+1
end

--以下我們創建對象來測試以下
local o1 = obj:new()
function o1:Sub()
	return 10-5
end
o1.id = 11;
--驗證結果
print(o1.id)
print(o1:Add())
print(o1:Sub())

2.cocos 使用class 實現繼承

1.先創建一個腳本 function.lua 實現下面方法
local setmetatableindex_
setmetatableindex_ = function(t, index)
    if type(t) == "userdata" then
        local peer = tolua.getpeer(t)
        if not peer then
            peer = {}
            tolua.setpeer(t, peer)
        end
        setmetatableindex_(peer, index)
    else
        local mt = getmetatable(t)
        if not mt then mt = {} end
        if not mt.__index then
            mt.__index = index
            setmetatable(t, mt)
        elseif mt.__index ~= index then
            setmetatableindex_(mt, index)
        end
    end
end
setmetatableindex = setmetatableindex_

--參數一:所要創建的類名,參數二:可選參數,可以使function,也可以是table,userdata等
function class(classname, ...) 
    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));
            cls.__create = super ----如果是個function,那麼就讓cls的create方法指向他
        elseif superType == "table" then ----如果是個table
            if super[".isclass"] then ----如果是個原生cocos類,比如cc.Sprite,不是自定義的
                -- super is native class
                assert(cls.__create == nil,string.format("class() - create class \"%s\" with more than one creating function or native class",classname));
                cls.__create = function() return super:create() end
            else
                -- 如果是個純lua類,自己定義的那種,比如a={}
                cls.__supers = cls.__supers or {}
                cls.__supers[#cls.__supers + 1] = super
                if not cls.super then
                    -- 把第一個遍歷到的table作爲cls的超類
                    cls.super = super
                end
            end
        else
            error(string.format("class() - create class \"%s\" with invalid super type",classname), 0)
        end
    end

    cls.__index = cls
    if not cls.__supers or #cls.__supers == 1 then --這個就是單繼承,設置cls的元表的index爲他的第一個超類
        setmetatable(cls, {__index = cls.super})
    else
        setmetatable(cls, {__index = function(_, key) --羨慕是多繼承,index指向一個函數,到時候找元素的時候會遍歷函數
            local supers = cls.__supers
            for i = 1, #supers do
                local super = supers[i]
                if super[key] then return super[key] end
            end
        end})
    end

    if not cls.ctor then
        -- 增加一個默認構造函數
        cls.ctor = function() end
    end
    cls.new = function(...)
        local instance
        if cls.__create then
            instance = cls.__create(...)
        else
            instance = {}
        end
        setmetatableindex(instance, cls)
        instance.class = cls
        instance:ctor(...)
        return instance
    end
    cls.create = function(_, ...)
        return cls.new(...)
    end
    return cls
end
2.實現過程 創建GameUserItem.lua文件
GameUserItem = class("GameUserItem")
--遊戲用戶數據模板
function GameUserItem:ctor()
	self.dwGameID		= nil			--遊戲(服務器)ID
	self.dwUserID		= nil			--用戶ID

	self.wFaceID 		= nil			--頭像標識
	self.dwCustomID		= nil			--自定義頭像

	self.cbGender		= nil			--性別
	self.cbMemberOrder	= nil			--成員排序
	
	self.szNickName =nil				--用戶暱稱
	self.szSign=nil						--個性簽名
	self.szAddress=nil					--聯繫地址
end
return GameUserItem
3.創建對象
	require ('Hall.GameModels.GameUserItem')--這裏根據你的真實路徑來require
	local userItem = GameUserItem:create() --創建對象
	userItem.dwGameID=1000
	userItem.szNickName='張三'
	--打印結果
	print(userItem.dwGameID)
	print(userItem.szNickName)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章