middleclass源码阅读笔记 lua中的面向对象(纯lua实现)
思路按照新类的建立流程
类的建立:
1,由middleclass直接创造出来的为类,或者父类
源码解析
- _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个
- _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 {}