Lua怎么实现面对对象
作者:互联网
Lua中的table就是一种对象
- table和对象一样可以拥有状态
- table和对象一样拥有一个独立于其值的标识(一个self): Lua只需要使用冒号,则能隐藏该self参数
- able和对象一样具有独立于创建者和创建地的生命周期
local table1 = {a = 1, b = 2} local table2 = {a = 1, b = 2} print(table1 == table2) -- return false
原理:lua面向对象编程是基于元表metatable,元方法__index来实现的
lua中的函数默认都是有self传递进去的,self相当于C++类中函数的this指针,语法糖会自动给我们传递 self
local a = { x = 1 } function a:print() print("function!"..self.x) end a.print(a) a:print()
面对对象原理(metatable元表 + _index原方法)
解释:元表像是一个备用查找表,假设表A的元表是B,那么在A中找不到的东西就会尝试在B中去找,设置元表的函数如下 setmetatable(A, B),这样表B就被设置为A的元表,当A中查找不到某个变量时就会到B中进行查找
A = {} B = {a = 1} -- must assign B to _index B._index = B -- set B as metatable of A setmetatable(A, B) -- can get variable that A doesn't contain but B contain print(A.a)
面对对象的封装
主要还是用table做类,新建对象用metatable和基对象做联系
Class = { x = 1, y = 2 } Class._index = Class -- same as constructure function Class:new(x, y) -- create a new object, so that the instance is independent local tempObj = {} tempObj.x = x tempObj.y = y -- set the metatable for the new object setmetatable(tempObj, Class) -- return the object return tempObj end function Class:add(val) self.x = x + val self.y = y + val end -- Test Code local Obj = Class:new(1, 2) Obj.add(2) print(Obj.x, Obj.y) -- print 3, 4
面对对象的继承和多态
-- SubClass that extends Class SubClass = { z = 0 } setmetatable(SubClass, Class) SubClass._index = SubClass -- constructure function function SubClass:new(x, y, z) -- call base class first local tempObj = Class:new(x, y) -- set SubClass as metatable not Class! setmetatable(tempObj, SubClass) -- assign value to z of SubClass tempObj.z = z return tempObj end -- override the Add() from Class function SubClass:Add(val) self.x = self.x + val * 2 self.y = self.y + val * 2 end -- test code local Obj = Class:new(1, 2) Obj:Add(5) -- x = 6, y = 7 local SubObj = SubClass:new(1,2,3) SubObj:Add(5) -- x = 11, y = 12, z = 3
封闭私密性
思路:通过两个table来表示一个对象。一个table用来保存对象的私有数据;另一个用于对象的操作。对象的实际操作时通过第二个table来实现的。为了避免未授权的访问,保存对象的私有数据的表不保存在其它的table中,而只是保存在方法的closure中function new(defaultName) local self = {name = defaultName} -- keep variable in table local setName = function (v) self.name = v end local getName = function () return self.name end return {setName = setName, getName = getName} -- only return method 只能通过newObject中创建的函数来访问这个self table end local object= new("aaa") object.setName("aaa") -- 不需要多余的self字段的,也就不用冒号了。 print(object.getName()) -- print aaa
Reference:
- https://blog.csdn.net/yzf279533105/article/details/80099358
- https://www.jianshu.com/p/467840d7ad13
标签:对象,self,SubClass,面对,Lua,print,--,local,Class 来源: https://www.cnblogs.com/cancantrbl/p/16050889.html