lua不是一个面向对象的语言,但是他又有面向对象的思想。lua中的面向对象是伪面向对象,伪面向对象就要用到table实现。
由table模拟了一个面向对象的编程, table其实也可以看做是一个对象,和其他语言对象一样有个自身的标示(self),具有自己的生命周期。本案例演示lua中的面向对象。
首先用table实现面向对象。
然后通过self得到当前lable对象。
接下来通过 : 符号实现声明函数时的隐试参数self。
最后通过require返回对象,调用该对象方法。
实现此案例需要按照如下步骤进行。
步骤一:用table实现面向对象
首先定义一个table类型的数据Account,然后声明label对象,通过对象调用方法,代码如下所示:
- Accout = {balance = 0}
- functionAccout.count( v )
- print ("value is "..v)
- end
- --声明label对象(变量)accout
- accout = Accout
- --通过对象调用方法
- accout.count(1000)
编辑器中的效果如图-13所示:
图-13
步骤二:通过self得到当前lable对象
通过对象调用方法,显示的把accout这个table 这个对象传入到函数 (显示的传入 self),还可通过冒号调用的方式隐试的传入self对象代码如下所示:
- Accout = {balance = 10}
- --显示传入self
- functionAccout.count( self, v )
- self.balance = self.balance + v;
- print ("value is "..self.balance)
- end
- --声明label对象(变量)accout
- accout = Accout
- --通过对象调用方法, 显示的把accout这个 table 这个对象传入到函数 (显示的传入 self)
- accout.count(accout, 1000)
- --还可通过 : 调用的方式隐试的传入 self 对象
- accout:count(2000)
编辑器中的效果如图-14所示:
图14
步骤三:通过冒号实现声明函数的隐式参数
通过冒号符号隐式传入self,还可通过冒号调用的方式隐式的传入self对象,代码如下所示:
- Accout = { balance = 10}
- --通过 : 符号, 隐试传入 self
- functionAccout:count( v )
- self.balance = self.balance + v;
- print ("value is "..self.balance)
- end
- --声明label对象(变量)accout
- accout = Accout
- --还可通过 : 调用的方式隐试的传入 self 对象
- accout:count(2000)
编辑器中的效果如图-15所示:
图-15
步骤四:通过require 返回对象
通过require 返回对象,调用该对象方法,代码如下所示:
- class = require("myClass")
- --函数写在 table的括号外
- class:showName()
- --函数写在 table的括号内
- class.show(class)
编辑器中的效果如图-16所示:
图-16
-------------》require(“XXX”) -- 只执行一次,避免了重复执行
本案例中,完整代码如下所示:
- --[[lua不是一个面向对象的语言,但是他又有面向对象的思想
- lua中的面向对象是伪面向对象,伪面向对象就要用到table实现,
- 是table模拟了一个面向对象的编程, table其实也可以看做是一个对象,
- 和其他语言对象一样有个自身的标示(self),具有自己的生命周期。]]
- --1.用table实现面向对象
- Accout = {balance = 0}
- functionAccout.count( v )
- print ("value is "..v)
- end
- --声明label对象(变量) accout
- accout = Accout
- --通过对象调用方法
- accout.count(1000)
- --2.通过 self 得到当前 lable 对象
- Accout = {balance = 10}
- --显示 传入 self
- functionAccout.count( self, v )
- self.balance = self.balance + v;
- print ("value is "..self.balance)
- end
- --声明label对象(变量) accout
- accout = Accout
- --通过对象调用方法, 显示的把 accout 这个 table 这个对象传入到函数 (显示的传入 self)
- accout.count(accout, 1000)
- --还可通过 : 调用的方式 隐试的传入 self 对象
- accout:count(2000)
- --3.通过 : 符号,实现声明函数时的 隐试参数 self
- Accout = { balance = 10}
- --通过 : 符号, 隐试 传入 self
- functionAccout:count( v )
- self.balance = self.balance + v;
- print ("value is "..self.balance)
- end
- --声明label对象(变量) accout
- accout = Accout
- --还可通过 : 调用的方式 隐试的传入 self 对象
- accout:count(2000)
- --4.通过require 返回对象, 调用该对象方法
- class = require("myClass")
- --函数写在 table的括号 外
- class:showName()
- --函数写在 table的括号 内
- class.show(class)
2、元方法与元表元方法:就是两个 类型 变量之间进行操作的 函数例如,1.数字的相加,它可能仅仅是一个函数:1 + 1--->add(1,1)--->add函数就是用来计算两个数字间相加的结果de2.table类型相加?--->Lua中不存在两个{} + {}的元方法!元表(metatable):就是用来存放 元方法 的 table,是table预定义的一系列操作。把两个table相加,那么Lua就会先去检查两个table是否有metatable,然后再检 查metatable中是否有__add方法。如果有按照__add方法中的操作来执行,否则,报错。例如,如果非要将两个table类型相加的话,直接运行必报错。但Lua允许修改元表,如下所示:一个元表,其实就是一个table值,所以,我们只需要新建一个table,添加元方法即可。
比如加法运算的元方法就是:__add,这是Lua规定的。
只要某个值的元表里含有__add这个元方法,那就可以使用+号进行运算。
如下代码:
首先创建了一个table变量mt,给这个table新增一个元素__add,这个table就拥有了作为元表的资格了。
然后创建两个新的table变量,使用setmetatable函数给table设置新的元表,此时,两个table变量就以mt作为元表了。
最后,对t1和t2进行加法操作,这时就会从元表中查找__add元方法,如果找到的话,就调用这个元方法对两个变量进行加法操作。
Lua中的每一个值都有或者可以有一个元表,但table和userdata可以拥有独立的元表,其他类型的值就只能共享其类型所属的元素。比如字符串使用的是string的元表。注意:Lua在新建table时,不会创建metatable,需要使用setmetatable来设置元表。setmetatable的参数可以使任意table,包括要赋值的table本身。------》查看一个变量是否有元表:print(getmetatable(a)) -- nil 表示没有元表Lua中的重要的元方法:__eq等于、__lt小于、__le小于等于、__add:加法、__sub:减法、__mul:乘法、__div:除法、__unm:相反数、__mod:取模、__pow:乘幂、__index function(table,key)、__newindex function(table,key,value)、__tostring 被print()调用、__metatable设置后可隐藏mt只要在自定义元表的时候,给这些元方法名赋予新的函数就可以实现自定义操作了。
Lua访问table元素 首先,通过__index元方法来查找是否有这个函数(如果没有,返回nil);__index的值可以直接是一个table,也可以是函数(若是table,则以该table作为索引进行查询;若是函数,则将table和缺少的域作为参数,调用这个函数)
例子1、
我们新建一个自定义的元表(也就是一个table变量),用来定义一些操作:
其实这和上一节的例子基本一样,只是多说一次而已,使用方式如下:
原文:http://blog.csdn.net/opera95/article/details/51082322