Lua学习笔记之面向对象

Lua的表在某种意义上也可以看做对象,表有状态(成员变量),可以有自己的成员函数。

一.“类”与“对象(instance)”的实现

为了使对象有独立的生命周期,故在定义方法的时候带上一个额外的参数,来表示方法的作用对象,在Lua中这个对象就是self.使用self参数定义函数后,这个函数就可以作用在多个对象上。

1.1 . 和 :的区别:

①使用.访问的方法,声明时需要带上一个额外的参数,表示方法作用的对象,这个参数为self,调用时参数列表要显式说明当前调用这个方法的对象

②使用:访问的方法,声明时可以隐藏self的参数声明,即冒号的效果相当于在函数定义和调用的时候

1.2示例代码

Account = {
	balance = 0,
	withdraw = function(self, v)
	self.balance = self.balance - v
	print(self.balance)
	end
}

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

--使用.参数列表要显式声明所属的对象
Account.deposit(Account,200.00)
--使用冒号则可以参数列表可以不传当前调用的对象
Account:withdraw(50.00)

a1 = Account;
Account = nil;
a1.withdraw(a1,100.0);
二.类的实现

Lua不存在类的概念,但是Lua是基于prototyoe的预言,所以在Lua中可以模仿类的概念。每个对象都有一个prototype,可以把这里对象拥有的prototype当做这个对象的父类,在Lua中prototype的设置可以通过给对象设置元表。而这个元表拥有__index元方法以及__newindex元方法,分别用于查找(对象调用它自己不存在的成员变量时会到它的prototype中查找) 更新.

a = Account : new{balance = 0}
a:deposit(666.00)--当在表a找不到deposit方法时,去Account中找
三.继承的实现

即可以让类访问其他类的方法。


--基类Account
Account = {balance = 0}

function Account:new(o)
	o = o or {}
	setmetatable(o,self)
	o.__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 "insufficient funds" end
	self.balance = self.banlance - v
end

--~ --从基类Account派生出一个子类SpecialAccount
--~ --增添功能:这个子类允许客户取款超过它的存款余额限制
SpecialAccount = Account:new()
s = SpecialAccount:new{limit = 1000.00} --当new方法执行时self参数指向SpecialAccount

--SpecialAccount的特殊之处在于可以重定义从类中继承来的方法
function SpecialAccount:withdraw(v)
	if v-self.balance >= self:getLimit() then
		error "insufficient funds"
	end
	self.balance = self.balance - v
end

function SpeicialAccount:getLimit()
	return self.limit or 0
end

四.多重继承:一个类有多个父类

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

4.1可以定义一个函数createClass来完成创建子类的功能,而通过给这个方法中定义的子类对象设置__index,而这个__index是一个函数,到search方法中去多个父类中查找子类对象中不存在的域.

--k为键 而plist是父类的集合
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 = {}	--新的子类
	--通过设置元表 可以遍历查找父类中的每个方法
	setmetatable(c,{__index = function(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

五.私有性

Lua的元机制(meta-mechanisms)可以实现很多不同的机制。状态可以被保存在方法的闭包内

函数创建一个表来描述对象的内部状态,并保存在局部变量self(故方法只能用.访问)中->函数为对象的每一个方法创建一个闭包(嵌套的函数实例)->函数创建并返回外部对象,而外部对象将局部方法指向最终要实现的方法。

--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)
print(d("get"))

d("set",10)
print(d("get"))





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值