您的位置:首页 > 编程语言 > Lua

Lua的面向对象程序设计

2015-04-27 11:44 513 查看
Account={balance=0}
function Account.withdraw(self,v)
self.balance=self.balance-v
end

a={balance=0,withdraw=Account.withdraw}
a.withdraw(a,260)

--面向对象语言常使用self参数,lua提供了通过使用冒号操作符来隐藏self参数的声明

function Account:withdraw(v)
self.balance=self.balance-v
end
a:withdraw(100.0)
--冒号的效果相当于在函数定义和函数调用的时候,增加一个额外的隐藏参数
--我们可以使用dot语法定义函数而用冒号语法调用函数,反之亦然,只要我们正确的处理好额外的参数.
--dot语法定义时要加上self参数,调用时要传入相应的对象,冒号语法不用self参数,调用时也不需要相应的参数对象


Lua中对象没有类,每个对象有一个原型prototype,当调用不属于对象的某些操作时,会最先会到prototype中查找这些操作。

Account={balance=0}

function Account:withdraw(v)
self.balance=self.balance-v
end

function Account:deposit(v)
self.balance=self.balance+v
end

function Account:new(o)--返回一个子对象
o=o or {}
setmetatable(o,self)--Account成为o的原型
self.__index=self
return o
end

a=Account:new{balance=0}
print(a.balance)--输出0
a:deposit(100.00)
print(a.balance)--输出100


Account={balance=0}

function Account:withdraw(v)
if v>self.balance then error"insufficient funds" end
self.balance=self.balance-v
end

function Account:deposit(v)
self.balance=self.balance+v
end

function Account:new(o)
o=o or {}
setmetatable(o,self)--Account成为o的原型
self.__index=self
return o
end

SpecialAccount=Account:new()

function SpecialAccount:getLimit()
return self.limit or 0
end
--子类可以重定义从父类中继承来的方法
function SpecialAccount:withdraw(v)
if v-self.balance>=self:getLimit() then
error"insufficeint funds"
end
self.balance=self.balance-v
end

s=SpecialAccount:new{limit=1000.00}

function s:getLimit()
return self.balance*0.1
end

s:withdraw(200.0)--该调用将运行SpecialAccount的withdraw方法,但是当
--方法调用self:getLimit时,最后的定义被触发.


多重继承:将函数用作__index。当一个表的metatable存在一个__index函数时,如果lua调用一个原始表中不存在的函数,Lua将调用这个__index指定的函数,这样可以用__index实现在多个父类中查找子类不存在的域。

--原型,相当于父类
Account={money=0}

function Account:save(v)
self.money=self.money+v
end

function Account:spend(v)
self.money=self.money-v
if self.money<0 then
error"there is not enough money"
end
end

function Account:new(o)
o=o or {}
setmetatable(o,self)
self.__index=self--首先在o的原型中查找,然后在原型的__index中查找
return o
end
--k是缺少的域,plist是table,其元素也是table
function search(k,plist)
for i=1,table.getn(plist) do
local v=plist[i][k]
if v then return v end
end
end

function createClass(...)
local c={}
--__index是函数时,Lua将table和其缺少的域作为参数调用这个函数
setmetatable(c,{__index=function(t,k) print(t,k) return search(k,arg) end})
c.__index=c
function c:new(o)
o=o or {}
setmetatable(o,c)
return o
end
return c
end

Named={}

function Named:getname()
return self.name
end

function Named:setname(s)
self.name=s
end

NamedAccount=createClass(Account,Named)
account=NamedAccount:new{name="paul"}
print(NamedAccount)
print(account:getname())

--[[
table: 0039C988
table: 0039C988    getname
paul
]]


私有性

function newAccount(initialBalance)
--存储在self表中的部分都是私有的
local self={balance=initialBalance}

local withdraw=function(v)
self.balance=self.balance-v
end

local deposit=function(v)
self.balance=self.balance+v
end

local getBalance=function() return self.balance end

return {
withdraw=withdraw,
deposit=deposit,
getBalance=getBalance
}
end

instance=newAccount(100)
print(instance.getBalance())
instance.withdraw(40)
print(instance.getBalance())


single-method的对象实现方法:当对象只有一个单一的方法时,可以将这个单一的方法作为对象返回

function newObject(value)
return function(action,v)
if action=="get" then return value
elseif action=="set" then value=v
else error("invalid action")
end
end
end
--每一个对象是一个单独的闭包,代价比表小得多,这种方式没有继承但有私有性:访问
--对象状态的唯一状态是通过它的内部方法
d=newObject(0)--d这个对象是newObject返回的单一方法
print(d("get"))--0
d("set",10)
print(d("get"))--10
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: