Lua中面向对象

时间:2023-01-02 10:32:21

一、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 ,这个函数被重载了。