Lua類和類繼承實現


Lua本身是不能像C++那樣直接實現繼承,但我們可以用萬能的table表來實現。

以下我總結了三種方式的類以及繼承的實現

第一、官方的做法,使用元表實現 原理參照《Programming in lua》

  Object.lua  

Object = {class_id = 0}
function Object:new(o)
    o = o or {}
    setmetatable(o,self) -- 對象o調用不存在的成員時都會去self中查找,而這里的self指的就是Object
    self.__index = self
return o
end

---以下我們創建對象來測試以下
local o1 =
Object:new()
o1.class_id = 11;
local o2 = Object:new()
o2.class_id = 22;
 
        

以上我們就利用元表實現了一個類,但這個類沒有任何行為,以下我們繼承上面的類

DisplayObject.lua

DisplayObject = Object:new()
-- 現在為止,DisplayObject只是Object的一個實例,注意以下代碼

D = DisplayObject:new(width = 100,height = 50)

-- DisplayObject從Object繼承了new方法,當new執行的時候,self參數指向DisplayObject。所以,D的metatable是DisplayObject,__index 也是DisplayObject。這樣,D繼承了DisplayObject,后者繼承了Object。

---在Lua中面向對象有趣的一個方面是你不需要創建一個新類去指定一個新的行為。

第二、復制表方式

 我們同樣使用上面的Object,換種寫法

--Lua中的面向對象  
--[[  
  復制表方式面向對象  
  參數為一張表,通過遍歷這張表取值,賦給一張空表,最后返回新建的表,來達到克隆表  
]]  
function cloneTab(tab)  
    local ins = {}  
    for key, var in pairs(tab) do  
        ins[key] = var  
    end  
    return ins  
end  

Object = {class_id = 1}

function Object.new()
  local o = cloneTab(Object)
  return o
end


-- 使用這個類
local p = Object.new()

繼承實現

DisplayObject.lua
--[[  
  復制表  
  第一參數是目標表,第二個參數是需要復制的表  
  通過遍歷tab來取值將它賦值到目標表中  
]]  
function copy(dist,tab)  
    for key, var in pairs(tab) do  
        dist[key] = var  
    end  
end 

DisplayObject = {}

function DisplayObject.new()
    local ss = Object.new()
    copy(ss,DisplayObject)
    return ss
end
local p1 =
DisplayObject.new()
 
        

第三,使用函數閉包的形式實現面向對象

--以函數閉包的形式實現面向對象  
  
--定義一個方法,函數閉包實現一個類的概念  
function People(name)  
    local self = {}  
  --初始化方法,私有的  
    local function init()  
        self.name = name  
    end  
    
    self.sayHi = function ()  
        print("Hello "..self.name)  
    end  
  
  --調用初始化  
    init()  
    return self  
end  
  
--實例化一個對象  
local p = People("ZhangSan")  
p:sayHi()  
  
--函數閉包的形式實現類繼承  
function Man(name)  
    local self = People(name)  
      
--  local function init()  
--        
--  end  
  
    self.sayHello = function ()  
        print("Hi "..self.name)  
    end  
      
    return self  
end  
  
local m = Man("Lisi")  
--m:sayHello()  
m:sayHi()

 

 

PS;關於繼承類,cocos2d-x v3版本提供一個更好更便捷的方式來實現。使用class全局方法創建

require "Object"

GameObject = class("GameObject",function ()
    return Object:new()
end)

function GameObject:create()
    return GameObject.new()
end
-- 以上就實現了一個繼承過程

在cocos引擎源代碼下有extern.lua這個文件,里面就聲明了class這個方法

extern.lua

function clone(object)
    local lookup_table = {}
    local function _copy(object)
        if type(object) ~= "table" then
            return object
        elseif lookup_table[object] then
            return lookup_table[object]
        end
        local new_table = {}
        lookup_table[object] = new_table
        for key, value in pairs(object) do
            new_table[_copy(key)] = _copy(value)
        end
        return setmetatable(new_table, getmetatable(object))
    end
    return _copy(object)
end

--Create an class.
function class(classname, super)
    local superType = type(super)
    local cls

    if superType ~= "function" and superType ~= "table" then
        superType = nil
        super = nil
    end

    if superType == "function" or (super and super.__ctype == 1) then
        -- inherited from native C++ Object
        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
        end

        cls.ctor    = function() end
        cls.__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

    else
        -- inherited from Lua Object
        if super then
            cls = clone(super)
            cls.super = super
        else
            cls = {ctor = function() end}
        end

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

        function cls.new(...)
            local instance = setmetatable({}, cls)
            instance.class = cls
            instance:ctor(...)
            return instance
        end
    end

    return cls
end

function schedule(node, callback, delay)
    local delay = cc.DelayTime:create(delay)
    local sequence = cc.Sequence:create(delay, cc.CallFunc:create(callback))
    local action = cc.RepeatForever:create(sequence)
    node:runAction(action)
    return action
end

function performWithDelay(node, callback, delay)
    local delay = cc.DelayTime:create(delay)
    local sequence = cc.Sequence:create(delay, cc.CallFunc:create(callback))
    node:runAction(sequence)
    return sequence
end

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM