lua中的面向对象编程opp

xiaoxiao2025-11-27  8


lua 通过table模拟出对象、状态(成员变量)、方法(函数)。 local Account = {blance = 100} --blance =》 变量, Account =》对象 function Account.Total(value) -- 函数 Account.blance = Account.blance + value print(Account.blance) end Account.Total(100) 上边这种写法很不好,在函数体内使用全局变量blance, 当我们改变Account时,函数体将不能使用。 我们采用下边这种写法可以避免: local Account = {blance = 100} function Account.Total(self, value) self.blance = self.blance + value print(self.blance) end Account.Total(Account, 100) 在面向对象编程语言中,都提供了像this、self等这样的用法,把自身传递进去。 lua也一样,lua中用(:)来表示self。 lua中(:)和(.)的区别,(:)代表传递了self参数。 上边的代码段通常我们这样写: local Account = {blance = 100} function Account:Total(value) self.blance = self.blance + value print(self.blance) end Account:Total(100) lua 中的类,lua中没有类的概念,我们可以通过table模拟出类。下边直接上代码: local Account = {} -- 类模版,账户默认有余额、账户、密码等信息 function Account.New() local tab = {} tab.blance = 0 tab.account = "www" tab.pssword = 12345 return tab end -- 测试 local my_account = Account.New() for k,v in pairs(my_account) do print(k,v) end -- 打印输出 --> pssword 12345 --> blance 0 --> account www lua 中实现继承 -- 基类,利用metatable来设置类模版 Account = {balance = 0} -- 银行账户 function Account:New(o) --创建账户 o = o or {} setmetatable(o, self) self.__index = self return o end function Account:Deposit(v) -- 存款 self.balance = self.balance + v end function Account:Withdraw(v) -- 取款 if v > self.balance then error("balance not enough!") end self.balance = self.balance - v end -- 派生类 下边派生一个特殊账户,可以透支取款1000 SpecialAccount = Account:New() -- 继承 function SpecialAccount:Withdraw(v) -- 相当于重写了基类函数 if v > self:GetLimit() then error("取款大于1000") end self.balance = self.balance - v print("剩余:" .. self.balance) end SA = SpecialAccount:New({limit = 1000}) -- sa的metatable 是 self function SA:GetLimit() return self.limit or 0 end -- 测试 SA:Withdraw(10000) -->报错 SA:Withdraw(1000) -->剩余:-1000

lua 中多重继承,这里不作细说有兴趣的小伙伴自行研究。

lua 中的私有性(private)   在Java、C#、C++等这些面向对象编程语言中,都提供了私有域保护机制。 lua不提供这样的机制,我们可以利用table模拟实现。下边我们要用到lua中的闭包机制。先研究一下闭包机制。

lua 闭包机制

先介绍几个术语:
1、词法定界:当一个函数内嵌另一个函数时,内函数可以访问外部函数的局部变量,这种特征叫做词法定界。2、第一类值(first class vlue):lua当中函数是一个值,他可以存在变量中,可以作为函数参数、返回值。3、外部局部变量(upvalue):当一个函数内嵌另一个函数时,外部函数的局部变量是内嵌函数的外部局部变量。4、闭包:通过调用含有一个内部函数加上该外部函数持有的外部局部变量(upvalue)的外部函数(就是工厂)产生的一个实例函数。 闭包 = 内嵌函数 + 外部函数 + upvalue 闭包代码测试: local ClosePack = {} function ClosePack.ClosePack() local value = 0 return function () value = value + 1 print(value) end end local test = ClosePack.ClosePack() test() --> 1 test() --> 2 test() --> 3 lua 私有性代码实现: function NewAccount(init_balance) local self = {balance = init_balance or 0} local deposit = function (v) -- 存款 self.balance = self.balance + v print("存款操作:" .. self.balance) end local withdraw = function (v) -- 取款 if v > self.balance then error("balance not enough!") end self.balance = self.balance - v print("取款操作:" .. self.balance) end return {deposit = deposit, withdraw = withdraw, } end -- 测试 这时只有NewAccount的实例才可以访问这些function local account = NewAccount(1000) account.deposit(500) --> 存款操作:1500 account.withdraw(600) --> 取款操作:900 在这里想到可以利用lua的闭包机制实现一个迭代器。迭代器需要记录上一次的运行状态和下一次成功执行的结果。 local Iteration = {} function Iteration.NewIteration(tab) -- 迭代器生成器 local i = 0 local len = #tab return function () i = i + 1 if i <= len then return tab[i] end end end -- 测试 local tab = {1, 2, 3, 4, 5, 6, 7, } local itera = Iteration.NewIteration(tab) while true do local element = itera() if nil == element then break else io.write(element .. ",") --> 1,2,3,4,5,6,7, end end print("\n") 介绍一种特殊的情况,对象只有一个单一的方法(Single_Method)。   这时我们不必像上边一样创建一个接口表,只需要在闭包中直接将这个function作为对象返回即可。 function NewObject(value) return function (action, v) if action == "get" then return value elseif action == "set" then value = v else error("输入有误!") end end end local obj = NewObject(10) print(obj("get")) --> 10 obj("set", 1000) print(obj("get")) --> 1000
转载请注明原文地址: https://www.6miu.com/read-5040082.html

最新回复(0)