这两天在看lua面向对象编程,在此记录一下自己看完后写的demo代码。
在Lua中,table就是一种对象,可以拥有状态与方法。如:
--[[
lua table实现OO
]]
-- base class
function personCreate(name, age)
local p = {name = name or ‘unknow‘, age = age or 0}
p.__index = p
setmetatable(p, p)
function p:setName(name)
self.name = name
end
function p:getName()
return self.name
end
function p:setAge(age)
self.age = age
end
function p:getAge()
return self.age
end
function p:toString(sep)
local _sep = sep or ‘, ‘
return ‘name:‘ .. self.name .. _sep .. ‘age:‘ .. self.age
end
return p
end
-- inherit
function studentCreate(name, age, score)
local s = personCreate(name, age) -- create base class object
s.score = score or 0
function s:setScore(score)
self.score = score
end
function s:getScore()
return self.score
end
function __toStringFactory(func)
function toString(self, sep)
local _sep = sep or ‘, ‘
return func(self, _sep) .. _sep .. ‘score:‘ .. self.score
end
return toString
end
-- override toString function
s.toString = __toStringFactory(s.toString)
return s
end
测试代码如下:
local student = studentCreate(‘billy‘, 28, 70) print(student:toString()) student:setScore(90) student:setName(‘Lily‘) print(student:toString(‘\t‘)) --[[ 输出结果: name:billy, age:28, score:70 name:Lily age:28 score:90 ]]
但是上面的代码还有一个问题,即对象的状态缺少封装性,我们可以不调用setter/getter,直接修改属性。要解决这个,可以通过两个table来表示一个对象,一个table用来保存对象的状态,另一个用于保存对象的方法(接口)。为了避免未授权的访问,表示状态的table不保存在其他的table中,只是保存在方法的closure中。下面的代码重新对上述的类进行设计:
--[[
lua closure实现OO
]]
-- base class
function personCreate(name, age)
local self = {name = name or ‘unknow‘, age = age or 0} -- upvalue
local p = {}
function p.setName(name)
self.name = name
end
function p.getName()
return self.name
end
function p.setAge(age)
self.age = age
end
function p.getAge()
return self.age
end
function p.toString(sep)
local _sep = sep or ‘, ‘
return ‘name: ‘ .. self.name .. _sep .. ‘age: ‘ .. self.age
end
return p
end
-- inherit
function studentCreate(name, age, score)
local self = {score = score or 0}
local s = personCreate(name ,age)
function s.setScore(score)
self.score = score
end
function s.getScore()
return self.score
end
function __toStringFactory(func)
function __toString(sep)
local _sep = sep or ‘, ‘
return func(_sep) .. _sep .. ‘scord: ‘ .. self.score
end
return __toString
end
-- override toString function
s.toString = __toStringFactory(s.toString)
return s
end
测试代码:
local student = studentCreate(‘billy‘, 28, 70) print(student.toString()) student.setName(‘Lily‘) student.setScore(90) print(student.toString(‘\t‘)) --[[ 输出结果: name: billy, age: 28, scord: 70 name: Lily age: 28 scord: 90 ]]
原文:http://my.oschina.net/kaedehao/blog/500429