zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    html5+plus(5+app) 扫一扫(plus.barcode)
    uniapp地图控件(浅显使用)
    sku排列算法,库存类展示(规格,型号,颜色等)
    『嗨威说』数据结构中常用的查找算法思路总结
    『ACM C++』 PTA 天梯赛练习集L1 | 057-063
    『ACM C++』 PTA 天梯赛练习集L1 | 054-056
    『ACM C++』 PTA 天梯赛练习集L1 | 052-053
    『ACM C++』 PTA 天梯赛练习集L1 | 050-51
    『ACM C++』 PTA 天梯赛练习集L1 | 048-49
    『ACM C++』 PTA 天梯赛练习集L1 | 046-47
  • 原文地址:https://www.cnblogs.com/kane0526/p/4826784.html
Copyright © 2011-2022 走看看