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

 

posted @ 2014-10-24 14:18  haroel  阅读(20191)  评论(0编辑  收藏  举报