1、类
基于原型。lua使用继承的思想即__index元方法来实现原型。
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 {}
self.__index = self
setmetatable(o, self)
return o
end
b = Account:new()
print(b.balance)
b:deposit( 200.00)
print(b.balance)
b:withdraw(100.00)
print(b.balance)
输出为:
0
200.0
100.0
2、继承
通过基类的new来创建基类的实例,然后实例再次new创建子类实例,通过重写实体方法来覆盖基类方法
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by wl.
--- DateTime: 2021/12/2 0:01
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 {}
self.__index = self
setmetatable(o, self)
return o
end
SpecialAccount = Account:new()
function SpecialAccount:withdraw(v)
if v - self.balance >= self:getLimit() then
error "insufficient funds"
end
self.balance = self.balance - v
end
function SpecialAccount:getLimit()
return self.limit or 0
end
s = SpecialAccount:new{limit = 1000.00}
print(s.balance)
s:deposit( 200.00)
print(s.balance)
s:withdraw(100.00)
print(s.balance)
3、多继承
原理仍然是使用元表,只是其__index中是在多个父类中查找。
local function search(k, plist)
for i = 1, #plist do
local v = plist[i][k]
if v then return v end
end
end
function createClass(...)
local c = {}
local parents = {...}
setmetatable(c, {__index = function(t,k)
return search(k, parents)
end})
c.__index = c
function c:new(o)
o = o or {}
setmetatable(o, c)
return o
end
return c
end
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 {}
self.__index = self
setmetatable(o, self)
return o
end
Named = {}
function Named:getName()
return self.name
end
function Named:setName(n)
self.name = n
end
NamedAccount = createClass(Named, Account)
account = NamedAccount:new{name = "Paul"}
print(account:getName())
一种优化方式是每次访问时,如果找到放到当前类中。缺点是如果对父类有修改,不会传递到子类中
setmetatable(c, {__index = function(t,k)
local v = search(k, parents)
t[k] = v
return v
end})
4、信息隐藏
通过闭包来实现。通过两张表,一张记录属性,一张记录操作。
function newAccount(initialBalance)
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
acc1 = newAccount(100.00)
acc1.withdraw(40.00)
print(acc1.getBalance())
输出为:
60.0
5、单方法
作为信息的分发
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)
print(d("get"))
d("set", 10)
print(d("get"))
输出:
0
10