cocos2d-Lua02Lua面向对象
1 Lua中的面向对象
1.1 问题
lua不是一个面向对象的语言。可是他又有面向对象的思想。
lua中的面向对象是伪面向对象。伪面向对象就要用到table实现。
由table模拟了一个面向对象的编程, table事实上也能够看做是一个对象。和其它语言对象一样有个自身的标示(self),具有自己的生命周期。本案例演示lua中的面向对象。
1.2 方案
首先用table实现面向对象。
然后通过self得到当前lable对象。
接下来通过 : 符号实现声明函数时的隐试參数self。
最后通过require返回对象,调用该对象方法。
1.3 步骤
实现此案例须要依照例如以下步骤进行。
步骤一:用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”) -- 仅仅运行一次,避免了反复运行
1.4 完整代码
本案例中。完整代码例如以下所看到的:
- --[[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这个元方法。那就能够使用+号进行运算。 例如以下代码:
- -- 创建一个元表
- local mt = {};
- mt.__add = function(t1, t2)
- print("两个table相加的结果就是...Good Good Study,Day Day Up!");
- end
- local t1 = {};
- local t2 = {};
- -- 给两个table设置新的元表
- setmetatable(t1, mt);
- setmetatable(t2, mt);
- -- 进行加法操作
- local result = t1 + t2;
首先创建了一个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变量)。用来定义一些操作:
- -- 创建一个元表
- local mt = {};
- mt.__add = function(s1, s2)
- local result = "";
- if s1.sex == "boy" and s2.sex == "girl" then
- result = "青梅竹马";
- elseif s1.sex == "girl" and s2.sex == "girl" then
- result = "空对空";
- else
- result = "硬碰硬"
- end
- return result;
- end
事实上这和上一节的样例基本一样。仅仅是多说一次而已,使用方式例如以下:
- -- 创建两个table,能够想象成是两个类的对象
- local s1 = {
- name = "Hello",
- sex = "boy",
- };
- local s2 = {
- name = "Good",
- sex = "girl",
- };
- -- 给两个table设置新的元表
- setmetatable(s1, mt);
- setmetatable(s2, mt);
- -- 进行加法操作
- local result = s1 + s2;
- print(result);
样例2、Window = {}Window.mt = {}Window.prototype = {x = 0,y = 0,width = 100,height = 100}Window.mt.__index = function(table,key)return Window.prototype[key]endfunction Window.new(t)setmetatable(t,Window.mt)return tend--測试w = Window.new{x = 10,y = 20}print(w.heigth)__newindex的使用方法基本与样例2一致。差别在于__newindex的作用是用于table的更新,__index用于table的查询操作。当对table中不存在的索引赋值时,就会调用__newindex元方法。组合使用__index和__newindex能够实现非常多功能封装:有了元表(metatable)之后。Lua类的封装就会变得非常easy。仅仅要为table加入metatable,并设置__index方法。比如:People = {age = 18}function People:new()local p = {}setmetatable(p,self)self.__index = selfreturn pendfunction People:groupUp()self.age = self.age + 1print(self.age)end--測试p1 = People:new()p1:growUp() --19p2 = People:new()p2:growUp() --19--[[执行结果能够看出:两个对象拥有的age成员是全然独立的。并且全部的有关People的方法都能够对外不可见,这样全然实现了面向对象中的类的封装--]]继承:继承是面向对象中不可缺少的一部分。依旧使用上例中的People,展示Lua中实现继承的方法。 创建一个People实例Man,再在Man上重写People的同名方法:Man = People:new()function Man:growUp()self.age = self.age + 1print("man's growUp:"..self.age)end--測试man1 = Man:new()man1.growUp() --man's growUp:19多态:Lua不支持函数多态,而支持指针的多态,因为Lua动态类型的特性,本身就能支持。person = People:new()person:growUp() --People's growUp:19person = Man:new()person:growUp() --Man's growUp:19
cocos2d-Lua02Lua面向对象的更多相关文章
- Cocos2d Lua 越来越小样本 内存游戏
1.游戏简介 一个"记忆"类的比赛游戏.你和电脑对战,轮到谁的回合,谁翻两张牌,假设两张牌一样.就消掉这两张牌,得2分,能够继续翻牌,假设两张牌不一样,就换一个人.直到最后.看谁的 ...
- angular2系列教程(六)两种pipe:函数式编程与面向对象编程
今天,我们要讲的是angualr2的pipe这个知识点. 例子
- 一起学 Java(二)面向对象
一.方法函数 函数也称为方法,就是定义在类中的具有特定功能的一段独立代码.用于定义功能,提高代码的复用性. 函数的特点1> 定义函数可以将功能代码进行封装,便于对该功能进行复用:2> 函数 ...
- js面向对象学习 - 对象概念及创建对象
原文地址:js面向对象学习笔记 一.对象概念 对象是什么?对象是“无序属性的集合,其属性可以包括基本值,对象或者函数”.也就是一组名值对的无序集合. 对象的特性(不可直接访问),也就是属性包含两种,数 ...
- 前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型
前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型 前言(题外话): 有人说拖延症是一个绝症,哎呀治不好了.先不说这是一个每个人都多多少少会有的,也不管它究竟对生活有多么大的 ...
- .NET 基础 一步步 一幕幕[面向对象之对象和类]
对象和类 本篇正式进入面向对象的知识点简述: 何为对象,佛曰:一花一世界,一木一浮生,一草一天堂,一叶一如来,一砂一极乐,一方一净土,一笑一尘缘,一念一清静.可见"万物皆对象". ...
- 简单分析JavaScript中的面向对象
初学JavaScript的时候有人会认为JavaScript不是一门面向对象的语言,因为JS是没有类的概念的,但是这并不代表JavaScript没有对象的存在,而且JavaScript也提供了其它的方 ...
- Java程序员应该了解的10个面向对象设计原则
面向对象设计原则: 是OOPS(Object-Oriented Programming System,面向对象的程序设计系统)编程的核心,但大多数Java程序员追逐像Singleton.Decorat ...
- JavaScript学习笔记(三)——this、原型、javascript面向对象
一.this 在JavaScript中this表示:谁调用它,this就是谁. JavaScript是由对象组成的,一切皆为对象,万物皆为对象.this是一个动态的对象,根据调用的对象不同而发生变化, ...
- 带你一分钟理解闭包--js面向对象编程
上一篇<简单粗暴地理解js原型链--js面向对象编程>没想到能攒到这么多赞,实属意外.分享是个好事情,尤其是分享自己的学习感悟.所以网上关于原型链.闭包.作用域等文章多如牛毛,很多文章写得 ...
随机推荐
- 【Linux运维-集群技术进阶】Nginx+Keepalived+Tomcat搭建高可用/负载均衡/动静分离的Webserver集群
额.博客名字有点长.. . 前言 最终到这篇文章了,心情是有点激动的. 由于这篇文章会集中曾经博客讲到的全部Nginx功能点.包含主要的负载均衡,还有动静分离技术再加上这篇文章的重点.通过Keepal ...
- PowerShell控制台字体设置
1.打开注册表: HKEY_CURRENT_USER\Console\%SystemRoot%_System32_WindowsPowerShell_v1.0_powershell.exe 2.找到键 ...
- Atitit 如何设置与安放知识的trap陷阱 知识聚合 rss url聚合工具 以及与trap的对比
Atitit 如何设置与安放知识的trap陷阱 知识聚合 rss url聚合工具 以及与trap的对比 1.1. 安放地点 垂直知识网站csdn cnblogs等特定频道栏目,大牛博客 1 1.2. ...
- PCIE 调试过程记录
遇到的问题 PCIE link不稳定 配置空间读写正常,Memory mapping空间读写异常 缘由 之前对PCIE的认识一直停留在概念的阶段,只知道是一个高速通讯协议,主要用于板内.板间的高速BU ...
- AlloyTouch全屏滚动插件搞定顺滑H5页
使用姿势 在设计全屏滚动插件的时候,希望开发者几乎: 不用写任何脚本快速生成精致H5 支持PC滚轮和移动触摸 酷炫的转场动效 灵活的时间轴管理 一切皆可配置 但是不写脚本肯定没有灵活性咯?!不是的.这 ...
- studying Bitcoin
https://github.com/bitcoinbook/bitcoinbook/blob/develop/book.asciidoc https://github.com/bitcoin/bip ...
- 源码分析HotSpot GC过程(三):TenuredGeneration的GC过程
老年代TenuredGeneration所使用的垃圾回收算法是标记-压缩-清理算法.在回收阶段,将标记对象越过堆的空闲区移动到堆的另一端,所有被移动的对象的引用也会被更新指向新的位置.看起来像是把杂陈 ...
- C++11 explicit的使用
C++中的explicit关键字只能用于修饰只有一个参数的类构造函数 , 它的作用是表明该构造函数是显示的, 而非隐式的,跟它相对应的另一个关键字是implicit, 意思是隐藏的,类构造函数默认情况 ...
- win7如何不用点击用户名 直接自动登录桌面
win7如何不用点击用户名 直接自动登录桌面 在win7系统中开机时必须点击相应的用户名才能登陆系统桌面那么如何取消这一功能使当前账户自动登录到系统桌面呢? 1 .在开始菜单搜索框输入 “netplw ...
- python 三元表达式 if for 构建List 进阶用法
1.简单的for...[if]...语句 Python中,for...[if]...语句一种简洁的构建List的方法,从for给定的List中选择出满足if条件的元素组成新的List,其中if是可以省 ...