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 ,這個函數被重載了。

 


免責聲明!

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



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