一 面向对象
(1)版本一
缺点:'违反'对象拥有'独立声明周期'的原则
(2)版本二
1. 方法需要一个'额外的参数'来表示接收者,这个参数通常被称为"self"或"self"
2. 参数self是所有'面向对象语言'的'核心点'
对操作的接收者进行操作
(3)版本三
++++++++++"冒号的作用"++++++++++
1、"定义"函数时,给函数添加"隐藏"的第一个参数 self -->定义时候用'.'点号
2、"调用"函数时,默认把当前'调用者'作为'第一个参数'传递进去 -->调用时候用':'冒号
++++++++++++++++"等价方式"++++++++++++++++
function Person.SetName(self,name)
function Person:SetName(name)
2)扩展
:call(a) -->"定义" -->'一个参数' --> '冒号定义'
==> "等价形式"
.call(self,a) -->"调用" -->'两个参数' --> '点号调用'
(4)Class 类
lua面向对象的机制:通过'__index'元方法来'模拟'实现的
① 理解setmetatable函数的返回值
② 类和对象
1. Lua语言中实际'没有类'的概念
2. 这里'用'基于原型的语言'prototype-based language'的一些做法在'lua'语言中'模拟'类
3. 这种'类'的特点:对象'不属于'类,但是每个对象都有一个'原型(prototype)'
4. 如何在"lua"语言中'表示一个类',"核心"是要创建一个'专门'被用作其它对象["类的实例"]的'原型'对象
+++++++++++++++++"实现的机制"+++++++++++++++++
1) 当对象"类的实例(instance)"遇到一个'未知操作'时 -->'__index'、'__newindex'
2) "首先"在'原型[重点]'中查找
备注: 后续对'instance1.count'的访问就'不会涉及'元方法了
③ 小技巧
④ 创建不同的实例
要使用这个"类"去创建'多个对象'
⑤ 案例
⑥ lua模拟单例模式
(5)lua模拟继承
Lua里的'继承'就是在'别人的table'里查找'自己不存在'的字段罢了
继承是指一个对象'直接使用'另一对象的属性和方法,可用于'扩展'基础类的"属性"和"方法"
① 单继承
1)重写父类的方法
做法: 给'子类'添加'同名,同参'的方法
2)给新实例添加独有的方法
优点:'无需'为了指定一种'新行为'而创建一个新类,直接在该'实例(对象)'上实现这个行为
② 多重继承
1) 单继承:把一个'table'用作__index的元方法-->该'table'实际就是'父类'
2) 多继承:要让'__index'元方法在其他'任意数量的父类中'查找'缺失'的键,此时'__index'指向一个'函数'
效果: 当在'原表'中找不到'一个键',就'调用'这个函数.
多继承: 顾名思义就是一个类有'多个超类'
++++++++++++++++++++"lua模拟实现方式"++++++++++++++++++++
1) 定义一个'独立的函数'来创建'子类[新类]' -->createClass
2) 函数的参数为'新类'的所有超类 -->(...) -->'可变参数'来容纳
3) 同时设置'新类'元表中的元方法__index,由元方法来实现'多继承'
1)版本一
++++++++++++++"实现机制"++++++++++++++
1) 由于在Child中不存在"getname"字段,所以从"Child的元表中"查找'__index字段'
2) 由于"__index"字段是一个函数,因此lua语言就调用这个函数,最终调用'search'函数
3) 该函数在'各个父类'中查找"getname";一旦在某一个父类中到一个'非nil的值',就返回该'父类'
2)版本二
版本一'缺点': 这种搜索每次'都要遍历',具有一定的'复杂性',性能'不如'单继承
改进: 一旦找到,将'被继承的方法'复制到子类中;在'第一次'访问被继承的方法后,'再访问'被继承的方法就会像'访问局部方法'一样快
++++++++++++"缺点"++++++++++++
1) 由于这种修改'不会'沿着继承层次'向下'传播
2) '无法'在系统开始运行后"修改"方法的定义
3) 小结
单继承与多重继承的"差别":一个是只'查找一个'table,另一个是查找'两个或以上'的table
(6)私有性 Privacy
1)私有变量
1) Lua语言中'标准'的对象实现方式'没有提供'私有性机制
2) 常见的做法:把所有的'私有名称'的最后'加上一个下划线'进行区分 --> "private_"
+++++++++++++++++++++++++++"实现机制"+++++++++++++++++++++++++++
返回的"table"中'只能only'通过add和sub访问number变量,这样就实现了'私有变量'
2)私有方法
私有方法的'关键点': 类似于公有方法,但"不放入接口"中
(7)单方法对象
Single-method Object
顾名思义:对象只有一个'方法'
+++++++++++++++"实现方式"+++++++++++++++
1. '不用'创建接口表
2. 将这个'单独的方法'以'对象的形式'返回
场景: 根据'不同的参数'完成'不同的任务'的分发方法(dispatch method) --> "私有方法"
++++++++++++"特点"++++++++++++
1) 这种方式'不能'实现"继承[inherit]",但可以拥有'完全的私有性'
2) 访问"单方法对象中的某个成员"只能通过'该对象的唯一方法'进行
补充:'Tcl/Tk'对它的'窗口部件'使用了'相似'的方法
(8)对偶表示
场景: 实现'私有性'的另一个'有趣的方式'是"对偶"表示 --> 'Dual Representation'
+++++++++++++"具体的表示"+++++++++++++
1. 把'表'当作'键';把'对象本身'当作'这个表'的键
key = {}
key[table] = value
备注: 通常使用'数值number'和'字符串string'来索引一个表,但可以使用'任何值'来索引一个'表'
重点: 这里使用'其它的表A'来索引一个'表B'
'优点':只有模块'内部的函数'才能访问
'缺点':把'表table2'作为'表tale1'中的键,这个帐号对于'垃圾收集器'而言永远也'不会变成'垃圾
(9)小结
备注: "不要使用"面向对象技巧
在lua中使用'面向对象的技巧'很是常见,他可以'提高代码的可读性',有利于代码的'模块化'还有'封装'.但是究竟面向对象技巧会有多少'性能损失'呢
二 杂谈
https://blog.csdn.net/zxm342698145/category_7528623.html