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