zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Visual Studio 正则表达式替换
    NHibernate MappingException. No Persister
    C#枚举
    测试
    NHibernate & INotifyPropertyChanged
    NHibernate Profiler使用方法
    根据条件动态拼接LinQ的where条件字串
    wpf中ToolTip实现
    jquery的colorbox关闭并传递数据到父窗
    c#简易反射调用泛型方法
  • 原文地址:https://www.cnblogs.com/howeho/p/4048201.html
Copyright © 2011-2022 走看看