Lua面向对象
Lua语言中的一张表可以理解为就是一个对象。
Lua中的表拥有一个标识self,类似于C++的this指针
Account = {num = 0}
function Account.withdraw(v)
Account.num = v
end
a = Account
Account = nil
a.withdraw(2) --error,因为该函数只能在Account.withdraw时使用
Account = {num = 0}
function Account.withdraw(self, v) --self表示对象本身
self.num = v
end
a = Account
Account = nil
a.withdraw(a, 2)
print(a.num) --2,现在withdraw函数每次只对self来操作
function Account:withdraw(v) --用":"定义函数,表明在方法中加了self这个隐藏参数
self.num = v
end
b = Account
b:withdraw(2)
print(b.num) --2
1、类
在面向对象中,每个对象是类的一个具体实例。
Lua中没有类的概念,每个对象有一个原型,该原型也是一个普通的对象。当对象遇到一个未知操作时会首先在原型中查找。
Lua中创建一个专门被用作其他对象的原型对象来表示类,使用元表和元方法来实现原型
对于对象A和B,如果使得B是A的一个原型,则:
setmetatable(A, {__index = B})
--此后,A会先在B中查找其没有的操作,
--例子
local Animal = {name = nil, age = nil}
function Animal:new(o)
local o = o or {}
setmetatable(o, {__index = Animal}) --调用“对象的成员”时,如果o中不存在,则会在__index所指定的表中去查找
return o
end
function Animal:setAge(age)
self.age = age
end
a1 = Animal:new{name = "Tom"} --创建一个Animal对象a1时,a1会将{__index = Animal}作为元表
print(a1.name, a1.age)
a1:setAge(20)
--[[
调用a1:setAge(20)时,实际上调用的是a1.setAge(p1, 20),Lua先在a1表中查找setAge,查找不到后去元表的__index中查找,getmetatable(a1).__index.setAge(a1, 20)即Animal.setAge(a1, 20)
--]]
print(a1.name, a1.age)
--改进后的构造函数
function Animal:new(o)
o = o or {}
self.__index = self --不再创建新的元表,而是直接将表本身作为元表
setmetatable(o, self)
return o
end
2、继承
-- 基类Animal
local Animal = {name = "", age = 0}
function Animal:new(o)
local o = o or {}
self.__index = self
setmetatable(o, self) --调用“对象的成员”时,如果o中不存在,则会在__index所指定的表中去查找
return o
end
function Animal:printInfo()
print("名字:"..self.name)
print("年龄:"..self.age)
end
-- 对于继承的子类,有新的属性或行为,只需在这个对象中添加属性和实现新的方法即可
-- 派生类Cat
Cat = Animal:new({variety = ""})
-- 派生类方法Talk
function Cat:Talk()
print("喵喵喵")
end
c1 = Cat:new{name = "Tom", age = 3, variety = "橘猫"}
c1:printInfo()
print(c1.variety)
c1:Talk()
-- 派生类Dog
Dog = Animal:new({variety = "未知"})
-- 派生类方法Talk
function Dog:Talk()
print("汪汪汪")
end
d1 = Dog:new{name = "Jack", age = 4}
d1:printInfo()
print(d1.variety)
d1:Talk()
--输出结果:
--[[
名字:Tom
年龄:3
橘猫
喵喵喵
名字:Jack
年龄:4
未知
汪汪汪
--]]
3、Lua程序设计课后习题
--Stack.Lua
local Stack = {st = {}, index = 0}
function Stack:new(o)
local t = o or {}
self.__index = self
setmetatable(t, self)
return t
end
function Stack:push(v)
table.insert(self.st, v)
self.index = self.index + 1
end
function Stack:pop()
if self.index== 0 then return false
end
local val = self.st[self.index]
self.st[self.index] = nil
self.index = self.index - 1
return val
end
function Stack:top(v)
if self.index == 0 then return false
end
return self.st[self.index]
end
function Stack:isempty(v)
return self.index == 0
end
return Stack
-- StackQueue.Lua
local Stack = require "Stack"
local StackQueue = Stack:new()
function StackQueue:new(o)
local t = o or {}
self.__index = self
setmetatable(t, self)
return t
end
function StackQueue:insertbottom(v)
table.insert(self.st, 1, v)
self.index = self.index + 1
end
return StackQueue