lua中的面向对象编程opp


  • lua 通过table模拟出对象、状态(成员变量)、方法(函数)。
local Account = {blance = 100} --blance =》 变量, Account =》对象
function Account.Total(value)	-- 函数
	Account.blance = Account.blance + value
	print(Account.blance)
end
Account.Total(100)
  • 上边这种写法很不好,在函数体内使用全局变量blance, 当我们改变Account时,函数体将不能使用。
    我们采用下边这种写法可以避免:
local Account = {blance = 100}
function Account.Total(self, value)
	self.blance = self.blance + value
	print(self.blance)
end
Account.Total(Account, 100)
  • 在面向对象编程语言中,都提供了像this、self等这样的用法,把自身传递进去。
    lua也一样,lua中用(:)来表示self。
    lua中(:)和(.)的区别,(:)代表传递了self参数。
    上边的代码段通常我们这样写:
local Account = {blance = 100}
function Account:Total(value)
	self.blance = self.blance + value
	print(self.blance)
end
Account:Total(100)
  • lua 中的类,lua中没有类的概念,我们可以通过table模拟出类。
    下边直接上代码:
local Account = {}
-- 类模版,账户默认有余额、账户、密码等信息
function Account.New()
	local tab = {}
	tab.blance = 0
	tab.account = "www"
	tab.pssword = 12345
	return tab
end
-- 测试
local my_account = Account.New()
for k,v in pairs(my_account) do
	print(k,v)
end
-- 打印输出
--> pssword	12345
--> blance	0
--> account	www
  • lua 中实现继承
-- 基类,利用metatable来设置类模版
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("balance not enough!")
	end
	self.balance = self.balance - v
end

-- 派生类 下边派生一个特殊账户,可以透支取款1000
SpecialAccount = Account:New()			-- 继承

function SpecialAccount:Withdraw(v)		-- 相当于重写了基类函数
	if v > self:GetLimit() then
		error("取款大于1000")
	end
	self.balance = self.balance - v
	print("剩余:" .. self.balance)
end

SA = SpecialAccount:New({limit = 1000})	-- sa的metatable 是 self

function SA:GetLimit()
	return self.limit or 0
end

-- 测试
SA:Withdraw(10000)	-->报错
SA:Withdraw(1000)	-->剩余:-1000
  • lua 中多重继承,这里不作细说有兴趣的小伙伴自行研究。

  • lua 中的私有性(private)

      在Java、C#、C++等这些面向对象编程语言中,都提供了私有域保护机制。
    lua不提供这样的机制,我们可以利用table模拟实现。下边我们要用到lua中的闭包机制。先研究一下闭包机制。

  • lua 闭包机制

先介绍几个术语:
  • 1、词法定界:当一个函数内嵌另一个函数时,内函数可以访问外部函数的局部变量,这种特征叫做词法定界。
  • 2、第一类值(first class vlue):lua当中函数是一个值,他可以存在变量中,可以作为函数参数、返回值。
  • 3、外部局部变量(upvalue):当一个函数内嵌另一个函数时,外部函数的局部变量是内嵌函数的外部局部变量。
  • 4、闭包:通过调用含有一个内部函数加上该外部函数持有的外部局部变量(upvalue)的外部函数(就是工厂)产生的一个实例函数。

    闭包 = 内嵌函数 + 外部函数 + upvalue
  • 闭包代码测试:
local ClosePack = {}
function ClosePack.ClosePack()
	local value = 0
	return function ()
		value = value + 1
		print(value)
	end
end
local test = ClosePack.ClosePack()
test()	--> 1
test()	--> 2
test()	--> 3
  • lua 私有性代码实现:
function NewAccount(init_balance)
	local self = {balance =	init_balance or 0}
	local deposit = function (v)	-- 存款
		self.balance = self.balance + v
		print("存款操作:"  .. self.balance)
	end

	local withdraw = function (v)	-- 取款
		if v > self.balance then 
			error("balance not enough!")
		end
		self.balance = self.balance - v
		print("取款操作:" .. self.balance)
	end

	return {deposit = deposit,
			withdraw = withdraw,
		}
end
-- 测试 这时只有NewAccount的实例才可以访问这些function
local account = NewAccount(1000)
account.deposit(500)	--> 存款操作:1500
account.withdraw(600)	--> 取款操作:900
  • 在这里想到可以利用lua的闭包机制实现一个迭代器。
    迭代器需要记录上一次的运行状态和下一次成功执行的结果。
local Iteration = {}
function Iteration.NewIteration(tab)	-- 迭代器生成器
	local i = 0
	local len = #tab
	return function ()
		i = i + 1
		if i <= len then
			return tab[i]
		end
	end
end

-- 测试
local tab = {1, 2, 3, 4, 5, 6, 7, }
local itera = Iteration.NewIteration(tab)
while true do
	local element = itera()
	if nil == element then
		break
	else
		io.write(element .. ",")	--> 1,2,3,4,5,6,7,
	end
end
print("\n")
  • 介绍一种特殊的情况,对象只有一个单一的方法(Single_Method)。

      这时我们不必像上边一样创建一个接口表,只需要在闭包中直接将这个function作为对象返回即可。
function NewObject(value)
	return function (action, v)
		if action == "get" then
			return value
		elseif action == "set" then
			value = v
		else
			error("输入有误!")
		end
	end
end

local obj = NewObject(10)
print(obj("get"))	--> 10
obj("set", 1000)
print(obj("get"))	--> 1000

温馨提示:
博主原创,请支持原创!
欢迎各位大佬不吝赐教!
联系方式:Q Q : 844262776
     微信 : 15225601365
lua中的面向对象编程opp