lua中基類和“繼承機制”


基類:基類定義了所有對於派生類來說普通的屬性和方法,派生類從基類繼承所需的屬性和方法,且在派生類中增加新的屬性和方法。

繼承:繼承是C++語言的一種重要機制,它允許在已定義的類的基礎上產生新類。

 

lua基類和C++基類極為相似,但是lua中卻沒有繼承這一說,更沒有所謂的派生類。lua只能通過一種行為(元表)來模擬C++繼承這一方法。

元表:lua中提供的元表是用於幫助lua數據變量完成某些非預定義功能的個性化行為,當它做某一種操作,然而self表中卻沒有定義實現這種操作的方法,那么為了實現這一操作便會去元表中找實現這一操作的方法。

如果每一層的元表都定義一種方法指向上一層要“繼承”的lua表,這樣是不是就和C++繼承一樣了,有木有!

元方法:C++中的繼承不會改變語言的常規行為。但是lua中卻提供了一種可以改變table行為的方法,有兩種可以改變的table行為:(__index元方法)查詢table及( __newindex元方法)修改table中不存在的字段

(1)__index元方法:當對元表中不存在的字段進行訪問時,得到的結果為nil。通過定義這個元表的__index,那個訪問結果將由這個方法決定。

這個方法也是“繼承”父類的方法。

(2)__newindex元方法:當對元表中不存在的字段進行賦值時,解釋器會先找到這個元表的__newindex,如果有就調用它,對__newindex指向的表進行賦值操作, 如果沒有才對self表進行賦值。

  1 --保存類類型的虛表
  2 local _class = {}
  3 
  4 GLOBAL_OBJ_COUNT = {}
  5 ENABLE_OBJ_COUNT = 0
  6 
  7 function FindClassName(target, depth)
  8     for key,value in pairs(_G) do
  9         if value == target then
 10             return key
 11         end
 12     end
 13 end
 14 
 15 function ClasCountRetain(c)
 16     local key = FindClassName(c)
 17     if GLOBAL_OBJ_COUNT[key] == nil then
 18         GLOBAL_OBJ_COUNT[key] = 1
 19     else
 20         GLOBAL_OBJ_COUNT[key] = GLOBAL_OBJ_COUNT[key] + 1
 21     end
 22 end
 23 
 24 function ClasCountRelease(c)
 25     local key = FindClassName(c)
 26     if GLOBAL_OBJ_COUNT[key] == nil then
 27         GLOBAL_OBJ_COUNT[key] = -100000--標識異常
 28     else
 29         GLOBAL_OBJ_COUNT[key] = GLOBAL_OBJ_COUNT[key] - 1
 30     end
 31 end
 32 
 33 
 34 
 35 
 36 function PrintLuaClassCount( ... )
 37     print("PrintLuaClassCount.............")
 38     for key,value in pairs(GLOBAL_OBJ_COUNT) do
 39         print("PrintLuaClassCount:"..key..":",value)
 40     end
 41 end
 42 
 43 
 44 function BaseClass(super)
 45 
 46     -- 生成一個類類型
 47     local class_type = {}
 48     -- 在創建對象的時候自動調用
 49     class_type.__init = false
 50     class_type.__delete = false
 51     class_type.super = super
 52 
 53     class_type.New = function(...)           --定義New成員方法
 54         -- 生成一個類對象
 55         local obj = {}
 56         obj._class_type = class_type
 57 
 58         -- 在初始化之前注冊基類方法
 59         setmetatable(obj, { __index = _class[class_type] })
 60 
 61         -- 調用初始化方法
 62         do
 63             local create 
 64             create = function(c, ...)         
 65                 if c.super then
 66                     create(c.super, ...)      --對所有基類都進行init
 67                 end
 68                 if ENABLE_OBJ_COUNT ~= 0 then
 69                     ClasCountRetain(c)
 70                 end
 71                 if c.__init then
 72                     c.__init(obj, ...)
 73                 end
 74             end
 75 
 76             create(class_type, ...)
 77         end
 78 
 79         -- 注冊一個delete方法
 80         obj.DeleteMe = function(self)
 81             local now_super = self._class_type 
 82             while now_super ~= nil do
 83                 if ENABLE_OBJ_COUNT ~= 0 then
 84                     ClasCountRelease(now_super)
 85                 end    
 86                 if now_super.__delete then
 87                     now_super.__delete(self)        --對所有基類都進行delete
 88                 end
 89                 now_super = now_super.super
 90             end
 91         end
 92 
 93         return obj
 94     end
 95 
 96     local vtbl = {}
 97     _class[class_type] = vtbl    
 98 
 99     setmetatable(class_type, {__newindex =
100         function(t,k,v)
101             vtbl[k] = v                      --賦值操作時self找不到的字段則對vtbl表賦值
102         end
103         , 
104         __index = vtbl, --For call parent method
105     })
106 
107     if super then
108         setmetatable(vtbl, {__index =       --元表做“繼承”操作
109             function(t,k)
110                 local ret = _class[super][k]
111                 return ret
112             end
113         })
114     end
115 
116     return class_type
117 end
View Code

 


免責聲明!

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



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