• Lua中面向对象


    一、Lua中类的简单实现:

    (1)版本——摘自 Cocos2.0中的:

    --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 

    下面是测试这段功能的代码片:

    ----------------------------------create  a father-------------------------------------------------
    local testClassbase = class("testClassbase")
    function testClassbase:ctor(data,closeUI)
            print(data)
        self.a = data
        print(self.a)
        self.b = closeUI
    end
     
    function testClassbase:print_member()
        print("-----data")
        print(self.a)
        print("===closeUI")
        print(self.b)
    end
    ---------------------------------main---------------------------------------------------------------------
    print("++++begin++++")
    testa =testClassbase.new(2,true)
    testa:print_member()    --注意这里要用冒号去调用

    如果要构造一个派生类来继承上面那个基类,那么需要加上下面这么一段

    function clone(object)                                       --clone函数  
        local lookup_table = {}                                 --新建table用于记录  
        local function _copy(object)                           --_copy(object)函数用于实现复制  
            if type(object) ~= "table" then   
                return object                                        ---如果内容不是table 直接返回object(例如如果是数字字符串直接返回该数字该字符串)  
            elseif lookup_table[object] then  
                return lookup_table[object]                   --这里是用于递归滴时候的,如果这个table已经复制过了,就直接返回  
            end  
            local new_table = {}  
            lookup_table[object] = new_table              --新建new_table记录需要复制的二级子表,并放到lookup_table[object]中.  
            for key, value in pairs(object) do  
                new_table[_copy(key)] = _copy(value)   --遍历object和递归_copy(value)把每一个表中的数据都复制出来  
            end  
            return setmetatable(new_table, getmetatable(object))--每一次完成遍历后,就对指定table设置metatable键值  
        end  
        return _copy(object)                                      --返回clone出来的object表指针/地址  
    end

    测试继承的代码:

    --------------------------------copy a child-----------------------------------------------------------
    local testClassChild = class("testClassChild",testClassbase)
     
    function testClassChild:ctor(data,UIclose)
           self.a = data
           self.b = UIclose
    end
     
    function testClassChild:Greet()
            self.sayhello()
        self:print_member()
    end
     
    ---------------------------------main---------------------------------------------------------------------
    print("++++begin++++")
    testa =testClassbase.new(2,true)
    testa:print_member()    --注意这里要用冒号去调用
     
    print("--------------------------")
    testb = testClassChild.new(4,false)
    testb:Greet()

    完整代码:

    --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  
     
     
    --------------------------------------------------clone_function--------------------------------------------------------------------------------
     
    function clone(object)                                       --clone函数  
        local lookup_table = {}                                 --新建table用于记录  
        local function _copy(object)                           --_copy(object)函数用于实现复制  
            if type(object) ~= "table" then   
                return object                                        ---如果内容不是table 直接返回object(例如如果是数字字符串直接返回该数字该字符串)  
            elseif lookup_table[object] then  
                return lookup_table[object]                   --这里是用于递归滴时候的,如果这个table已经复制过了,就直接返回  
            end  
            local new_table = {}  
            lookup_table[object] = new_table              --新建new_table记录需要复制的二级子表,并放到lookup_table[object]中.  
            for key, value in pairs(object) do  
                new_table[_copy(key)] = _copy(value)   --遍历object和递归_copy(value)把每一个表中的数据都复制出来  
            end  
            return setmetatable(new_table, getmetatable(object))--每一次完成遍历后,就对指定table设置metatable键值  
        end  
        return _copy(object)                                      --返回clone出来的object表指针/地址  
    end 
     
    ----------------------------------create a father-------------------------------------------------
    local testClassbase = class("testClassbase")
    function testClassbase:ctor(data,closeUI)
    --        print(data)
        self.a = data
    --    print(self.a)
        self.b = closeUI
    end
     
    function testClassbase:sayhello()
          print("father say hello")
    end
     
    function testClassbase:print_member()
        print("-----data")
        print(self.a)
        print("===closeUI")
        print(self.b)
    end
     
    --------------------------------copy a child-----------------------------------------------------------
    local testClassChild = class("testClassChild",testClassbase)
     
    function testClassChild:ctor(data,UIclose)
           self.a = data
           self.b = UIclose
    end
     
    function testClassChild:Greet()
            self.sayhello()
        self:print_member()
    end
     
    ---------------------------------main---------------------------------------------------------------------
    print("++++begin++++")
    testa =testClassbase.new(2,true)
    testa:print_member()    --注意这里要用冒号去调用
     
    print("--------------------------")
    testb = testClassChild.new(4,false)
    testb:Greet()

    (2) 版本:

    据说是云风大神写的:

    这个是构造class的函数和上面的构造方法有很大的不同:

    具体讲解我找了一篇写的还不错的博客:http://blog.csdn.net/mywcyfl/article/details/37706085

    下面代码可以直接拿来运行:

    local _class={}  
    function class(super)  
        local class_type={}  
        class_type.ctor     = false  
        class_type.super    = super  
        class_type.new      =   
            function(...)  
                local obj={}  
                do  
                    local create  
                    create = function(c,...)  
                        if c.super then  
                            create(c.super,...)  
                        end  
                        if c.ctor then  
                            c.ctor(obj,...)  
                        end  
                    end  
      
                    create(class_type,...)  
                end  
                setmetatable(obj,{ __index = _class[class_type] })  
                return obj  
            end  
        local vtbl={}  
        _class[class_type]=vtbl  
      
        setmetatable(class_type,{__newindex=  
            function(t,k,v)  
                vtbl[k]=v  
            end  
        })  
          
        if super then  
            setmetatable(vtbl,{__index=  
                function(t,k)  
                    local ret=_class[super][k]  
                    vtbl[k]=ret  
                    return ret  
                end  
            })  
        end  
      
        return class_type  
    end 

    测试代码:

    base_type=class()                -- 定义一个基类 base_type  
    function base_type:ctor(x)       -- 定义 base_type 的构造函数  
        print("base_type ctor")  
        self.x=x  
    end  
     
    function base_type:print_x()     -- 定义一个成员函数 base_type:print_x  
        print(self.x)  
    end  
    function base_type:hello()        -- 定义另一个成员函数 base_type:hello  
        print("hello base_type")  
    end  
      
    test=class(base_type)            -- 定义一个类 test 继承于 base_type  
    function test:ctor()             -- 定义 test 的构造函数  
        print("test ctor")  
    end  
    function test:hello()            -- 重载 base_type:hello 为 test:hello  
        --test.super:hello()  
        print("hello test")  
    end  
      
    a=test.new(2)                   -- 输出两行,base_type ctor 和 test ctor 。这个对象被正确的构造了。  
    a:print_x()                     -- 输出 1 ,这个是基类 base_type 中的成员函数。  
    a:hello()                       -- 输出 hello test ,这个函数被重载了。
  • 相关阅读:
    优化C/C++代码的小技巧
    闭包,看这一篇就够了——带你看透闭包的本质,百发百中
    7215:简单的整数划分问题
    常见问题最佳实践三:服务启动顺序
    JAVA 用分苹果来理解本题
    arcgis访问格式
    墨卡托投影
    C# 从DataTable中取值
    Base64编码的字符串与图片的转换 C#
    墨卡托投影实现
  • 原文地址:https://www.cnblogs.com/cjn123/p/10666118.html
Copyright © 2020-2023  润新知