本帖最后由 wuojbk 于 2021-8-23 17:27 编辑
首先这篇帖子不适合小白食用,需要有基本面向对象使用基础和lua基础 集合理解。
学习lua面向对象基础 移步[Lua语言基础]-11、Lua面向对象编程概念
我看到群里有些兄弟觉得lua的面向对象繁琐 不好用 没有直接写函数暴力 通俗易懂。
这里我讲一下进阶后的面向对象。
- <font color="#ff0000"><b>这里我纯手撸 引用的他人例子 二次讲解尽量通俗易懂。</b></font>
复制代码
- local tree = {} --创建一个对象 集合
- tree.leafColor = "green" -- 为这个table添加属性 对象里也叫成员变量
- tree.height = 50 -- 为这个table添加属性 对象里也叫成员变量
- --我们来添加一个构造方法,什么是构造方法呢 相信很多有其他语言基础的兄弟都知道 构造方法 就是当你执行这个类也就是对象之前 优先执行的方法 也可以称之为钩子 就是在
- 执行你对象中方法时 先执行构造方法里的逻辑。
- --因为Lua里没有对象概念所以 我们是仿造的 仿造其他语言new一个对象 所以构造方法我们可以用new来命名 你想换别的名也可以 随意。
- function tree:new(color,height) ---- 构造对象的方法
- local instance = {} ----- 这里我们在构造方法里 在创建一个对象table
- setmetatable(instance,{__index = self}) ----设置元表 这里我们传入创建好的新对象table 然后把self 这是个语法糖 不懂得可以去看面向对象基础
- --setmetatable
- --这是这个函数的解释 给指定表设置元表。 (你不能在 Lua 中改变其它类型值的元表,那些只能在 C 里做。) 如果 metatable 是 nil, 将指定表的元表移除。 如果原来那--张元表有 "__metatable" 域,抛出一个错误。
- return instance -----返回我们创建的新对象,这里因为我们已经把metatable 赋值了 所以我们返回去的这个对象 将拥有 tree所有的成员和方法。
- end
- function tree:grow(year) -----我们给tree添加了一个方法 这个方法被我们在构造方法里创建的新对象instance所拥有
- print("tree:grow")
- print(self.height+year)
- self.height = self.height+year*0.5
- end
- local atree = tree:new() --这里我们调用tree的构造方法 但其实返回来的是我们构造方法里的新方法 instance 这个新方里拥有tree的所有属性和方法。
- print(atree:grow()) --这里我们调用grow 但其实他首先我们先执行的tree:new() 所以接下来我们调用的所有方法 都会先去执行tree:new()
- --这里 就比如说 我们开发一个游戏 这个游戏每次执行任务的时候都需要回到 固定的界面 比如主城 正常我们来写肯定需要写一个 验证主城的方法 然后每次调用其他任务的时候
- 都需要先调用验证主城()这个方法 是不是很麻烦 代码很冗余 当我们有了构造方法 只要我门把验证主城写入到构造方法里 当每次执行任务的时候 先调用构造方法 是不是就
- 解决了我们这个问题呢。
- --接下来说一下继承 有其他语言的兄弟 知道 其他语言 继承一般用关键字 extends 来继承 有的兄弟如果上面理解的通透 已经知道在Lua里的继承应该怎么写了。
- local atree = tree:new() --这是我们第一个对象 下面我们来继承他
- local btree = atree --这里atree是什么 是个对象也就是{} 我们新建一个btree
- function btree:new()
- --这里大家看着眼熟么
- local instance = {} -----我们又创建一个对象table 这个对象跟谁都没有关系 就是我们btree的一个新的构造方法。
- setmetatable(instance,{__index = self}) ----设置元表 这里我们把atree的所有属性和方法都交给instance
- return instance -----返回对象 返回的这个对象包含了 btree所有的属性和方法➕atree所有的属性和方法。 这里肯定会有人有疑问 明明不是说把atree给了他
- --为什么 btree的属性和方法也给他了 这里我们给的self 是btree 但是btree继承了atree btree = atree 就是说白了把btree的方法和atree的方法集合一起给了他。
- end
- function btree:grow(year)
- print("这里是重写btree后的新方法") --这里btree写了一个新的方法叫grow 这个方法 atree里也有 这就好比{atree="grow"} btree继承了之后{btree="grow"}
- --这就是先后顺序的问题 a = 1 b = a b = 1 这时候b他就等于1
- end
- print(atree:grow(10)) --这里还是atree的grow
- print(btree:grow(10)) --这里就是b继承了a后 重构也叫重写 覆盖了 a的grow 只要你不跟a重名 你写的什么方法都不会重构-覆盖掉a的方法。
- --这里大家又会有一个疑问 为什么btree:new() 没有重构掉atree:new() 这里大家在好好仔细想一下 我们在new里建的新对象instance的作用。
- 估计基础不牢的兄弟看完了之后可能会蒙 没关系 你只要把对象理解了,你在按照我这个例子去试 多测试几次 明白他的运行原理 就能懂了。
- 还有兄弟可能还觉得 我直接写函数 暴力传参很香 不繁琐麻烦顺序执行, 这里我建议当你写一个项目 写的方法多了 遇到问题了,回头想一想如果我拿对象来写是否能解决你的
- 问题。</font>
复制代码
还是那句话 大佬轻喷 有觉得不对的地方望指出。觉得有用的兄弟多多转载,让更多的兄弟一起进步 加油。
|