- 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
-- 基类,利用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
先介绍几个术语:
- 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
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
温馨提示: 博主原创,请支持原创! 欢迎各位大佬不吝赐教! 联系方式:Q Q : 844262776 微信 : 15225601365
|
请发表评论