Account = {balance = 0}
function Account.withdraw(v)
Account.balance = Account.balance - v
end
Account.withdraw(100)
print(Account.balance)
------------------------------------------------------------------------------------------------
--[[
在函数中使用全局名称是一个不好的编程习惯。
因为这个函数只能针对特对象工作,并且,这个特定对象还必须存储在特定的全局变量中。
--]]
-- a = Account Account = nil --> 因为函数withdraw(v)中使用了Account.balance,此时Account = nil
-- a.withdraw(100)
-- 当改成如下,withdraw中去掉Account.balance,调用正常
function Account.withdraw(v)
print "1"
end
a = Account Account = nil
a.withdraw(100)
------------------------------------------------------------------------------------------------
Account = {balance = 0}
-- 解决方案:
-- 指定一项操作所作用的“接受者”。
-- 需要一个额外的参数来表示该接受者。
-- 这个参数通常称为self或this
function Account.withdraw(self, v)
self.balance = self.balance - v
end
a1 = Account Account = nil
a1.withdraw(a1, 100)
------------------------------------------------------------------------------------------------
Account = {balance = 0}
-- Lua只需使用冒号,则能隐藏该参数self。只是一种语法便利,并没有引入任何新的东西。
--重写:function Account.withdraw(self, v)
function Account:withdraw(v)
self.balance = self.balance - v
end
------------------------------------------------------------------------------------------------
-- 用点语法来定义一个函数,并用冒号语法调用它。
Account = {
balance = 0,
withdraw = function (self, v) -- 1. 点语法定义
self.balance = self.balance - v
end
}
function Account:deposit(v) -- 2. 冒号语法定义
self.balance = self.balance + v
end
Account:withdraw(100.00) -- 1. 冒号语法调用
Account.deposit(Account, 200) -- 2. 点语法调用
Account:deposit(200) -- 2. 冒号语法调用
------------------------------------------------------------------------------------------------
--[[
类
--]]
-- example
-- 1. 检查该table中是否有这个key,若无
-- 2. 检查该table是否设置过metatable,若有
-- 3. 检查metatable中是否有__index,若有
-- 4. 检查__index下是否有这个key,若有
-- 5. 返回getmetatable(x).__index.key
local kid = {}
local father = {property = 11}
setmetatable(kid, father) -- 设置元表,仅仅设置元表并不能使lua寻找父类的方法或属性
father.__index = father -- 设置元方法(注意是设置父!)
father.anotherProperty = 22 -- 给fahter表增加一个属性
kid.money = 33 -- 给kid表增加一个属性
print(kid.property) -- 11, 返回父类father中property的值
print(kid.anotherProperty) -- 22,父类增加的属性和方法都可以被子类继承
print(father.money) -- nil,相反,父类并不可以获取子类的值
-- 创建更多与Account行为类似的账号(实例化)
-- 具体做法就是使用__index元方法 setmetatable(a, {__index = b})
function Account:new(o)
o = o or {} -- 如果用户没有提供table,则创建一个
setmetatable(o, self)
self.__index = self
return o
end
yqbAccount = Account:new{balance = 0}
yqbAccount:deposit(999.00)
print("balance of yqbAccount: ", yqbAccount.balance)
------------------------------------------------------------------------------------------------
--[[
继承
--]]
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 "insufficient funds"
end
self.balance = self.balance - v
end
-- 想派生可以透支的SpecialAccount
-- 创建一个空的类,继承了Account的所有方法(包括new)和属性
SpecialAccount = Account:new()
-- 实例化一个SpecialAccount,这次执行new时,它的self参数表示为SpecialAccount
s = SpecialAccount.new{limit = 1000.00}
function SpecialAccount:getLimit()
return self.limit or 0
end
-- 重写
function SpecialAccount:withdraw(v)
if v - self.balance >= self.getLimit() then -- 超过了透支值,不给透支
error "insufficient funds"
end
self.balance = self.balance - v
end
Lua面向对象编程
最新推荐文章于 2025-05-31 14:06:23 发布