LUA中的OOP(1) --- 类和对象

在不明确为OO而生的语言里玩OO往往是一件非常有趣的事情,因为语言层本身不支持,所以为了达到OO的效果就必须要深入这门语言进行研究和探索,即所谓"深入语言编程"。

于是这次来看一看在LUA里怎么OO,方法取自《lua中文手册》Chapter 16,这里做个整理和记录,顺带写一些心得。

如何定义对象和类:

       LUA是弱类型脚本语言,因此在LUA里类型感很缺失。因此并没有一个明确的"类"和"对象"的概念,这点和C++大不同。LUA里我们首先用Table实现一个对象,该对象作为"原型对象"充当类的职能。通过传递一个新的table给原型对象的特定方法,将该Table构造为一个和原型对象一样的新对象实例(跟构造函数一个意思),是LUA里常见的OO技术之一,代码类似这样:

<!- Code Begin>

do

--成员函数定义

local function _set_age(self, value)

self.age = value

end


--成员函数定义

local function _print_age(self)

print(string.format("age = %d", self.age)

end


--原型对象中的对象生成函数

local function _new(self, newobj, agevalue)

newobj = newobj or {}

self.__index = self

setmetatable(newobj, self)

newobj.age = agevalue;

return newobj

end


--定义原型对象,以及该对象需要公开的所有方法

human = {

age = 27,

set_age = _set_age,

print_age = _print_agem

new = _new

}

end



-- 使用原型对象,进行对象实例化

Boy1 = human:new(Boy1, 10)

Boy2 = human:new(Boy2, 5)

-- 通过下面的语句可以看出来,Boy2和 Boy1是两个完全独立的对象,拥有自己的数据成员。但是这是为什么?

Boy1:print_age()

Boy1:set_age(20)

Boy1:print_age();

Boy2:print_age();


<!-Code End>


关于上面问题的解释:

这就是所谓"深入语言编程"和"使用语言编程的区别"。还是来看human:_new()函数,self.__index = self,使得调用时human.__index = human,这样human本身就成为了一个metatable,随后的setmetatable(newobj,self) 调用,为newobj设置metatable为human,这里就是关键点。newobj的metatable.__index = human,就意味着当从newobj中读取任何数据时,如果不存在则转入human中继续读取(human也是一个Table),但是如果你为存在于human中的一个属性赋值,则因为lua是弱语言,那么在newobj中会直接添加和这个属性同名的成员,这样下次你再读取该属性时,直接就从newobj中取值了(因为你刚才的赋值操作为newobj添加了这个变量成员),这样一来,newobj也就拥有了属于自己的成员变量(推广到每一个调用human:new()产生的对象身上,就知道这些对象是原型对象的相互独立实例了)。

这里利用的lua特性有2个:1.metatable的__index操作符 2.lua作为弱语言,不要求先声明后使用。 至于 self.__index = self,一方面是一种优化,令原型对象本身直接作为metatable,节省一个table的开销,更重要的是为OO的另一个特性"继承"提供了基础。关于继承下次再说。现在下班走人吃饭去% :-)


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值