middleclass源码阅读笔记

来源:互联网 发布:内涵吧源码 编辑:程序博客网 时间:2024/06/05 06:07

middleclass源码阅读笔记 lua中的面向对象(纯lua实现)

思路按照新类的建立流程

类的建立:
1,由middleclass直接创造出来的为类,或者父类

源码解析
1. _createClasss(aClass, super)

name 类名 string
super 父类表 (没有父类时不存在这个域)
static 静态表
__instanceDict 实例表 存放类定义的属性和函数(包含父类)
__decaredMethod 声明表(当前类声明的方法,不包含父类)
subclasses 子类表, 使用弱引用

创建的新类的元方法
local function _tostring(self) return “class ” .. self.name end
local function _call(self, …) return self:new(…) end

class.__index -> class.static -> dict(rawget) 默认都为空表
–index可以更改为其它函数

通过元方法建立类索引的规则

2.DefaultMixin(将要添加到类中的表,前面开始建立的类是空的)

2.1 __tostring (将要添加到类的声明表和实例表默认方法) 默认tostring方法

2.2 initialize (将要添加到类的声明表和实例表的默认方法) 初始化方法 类似于构造函数,一般需要重写

2.3 isInstanceOf (将要添加到类的声明表和实例表的默认方法) 判断是否是某个类的实例

–通过class __newindex元方法,_declareInstanceMethod添加

具体见此函数实现
_declareInstanceMethod 添加到声明方法,继续调用_propagateInstanceMethod添加到实例方法,其中有一些过滤

2.4 static 类静态方法(不会添加到声明表和实例表的方法)

2.4.1 allocate (将要添加到类的静态表默认方法) 创建一个实例表,类似分配空间

2.4.2 new (将要添加到类的静态表默认方法) 通过allocate创建表,并调用initialize方法

2.4.3 subclassed (将要添加到类的静态表默认方法) subclassed 创建子类后的回调

2.4.4 subclass (将要添加到类的静态表默认方法)

为类添加一个指定名字的子类,并返回子类
创建指定名字的类,父类为自己
将父类的__instanceDict中的所有域,复制到子类中
子类的initialize 默认调用父类的initialize
在自己的subclass索引中,添加子类的索引
调用自己的subclassed方法,参数为子类

2.4.5 subclass isSubclassOf (将要添加到类的静态表默认方法) 是否是指定类的子类

2.4.6 include (将要添加到类的静态表默认方法) 将参数合并到本类中,声明和实例

类声明表方法,实例表方法3个,静态表方法6个

  1. _includeMixin(aClass, mixin)

将一张表合并到另一张表中,特殊处理static表(不能直接赋值,直接赋值为引用类型)

included, DefaultMixin引用类中的方法,实例才构造

_declareInstanceMethod

注册到__declaredMethods
如果f为nil,则去父类取该字段
将域添加到子类中

_propagateInstanceMethod

如果name = __index, 调用_createIndexWrapper
将f添加到aClass.__instanceDict[name]中
遍历所有子类,如果子类不包含该方法,则添加到子类中(若包含,相当于重写)

_createIndexWrapper(aClass, f)
f为空,则返回aClass.__instanceDict
如果__instanceDict包含name 则返回 <==> __index = __instanceDict
如果f为函数, __index = f(self,name)
否则,返回f[name]

类调用_call调用静态的new方法

以上是创建类和建立类实例的过程

及时更新子类方法

for subclass in pairs(aClass.subclasses) do
if rawget(subclass.__declaredMethods, name) == nil then
_propagateInstanceMethod(subclass, name, f)
end
end

inlude 特性_createIndexWrapper mixin.static or {}