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对象。通过对象调用方法,代码例如以下所看到的:

  1. Accout = {balance = 0}
  2. functionAccout.count( v )
  3. print ("value is "..v)
  4. end
  5. --声明label对象(变量)accout
  6. accout = Accout
  7. --通过对象调用方法
  8. accout.count(1000)

编辑器中的效果如图-13所看到的:

图-13

步骤二:通过self得到当前lable对象

通过对象调用方法。显示的把accout这个table 这个对象传入到函数 (显示的传入 self),还可通过冒号调用的方式隐试的传入self对象代码例如以下所看到的:

  1. Accout = {balance = 10}
  2. --显示传入self
  3. functionAccout.count( self, v )
  4. self.balance = self.balance + v;
  5. print ("value is "..self.balance)
  6. end
  7. --声明label对象(变量)accout
  8. accout = Accout
  9. --通过对象调用方法, 显示的把accout这个 table 这个对象传入到函数 (显示的传入 self)
  10. accout.count(accout, 1000)
  11. --还可通过 : 调用的方式隐试的传入 self 对象
  12. accout:count(2000)

编辑器中的效果如图-14所看到的:

图14

步骤三:通过冒号实现声明函数的隐式參数

通过冒号符号隐式传入self。还可通过冒号调用的方式隐式的传入self对象,代码例如以下所看到的:

  1. Accout = { balance = 10}
  2. --通过 : 符号, 隐试传入 self
  3. functionAccout:count( v )
  4. self.balance = self.balance + v;
  5. print ("value is "..self.balance)
  6. end
  7. --声明label对象(变量)accout
  8. accout = Accout
  9. --还可通过 : 调用的方式隐试的传入 self 对象
  10. accout:count(2000)

编辑器中的效果如图-15所看到的:

图-15

步骤四:通过require 返回对象

通过require 返回对象,调用该对象方法,代码例如以下所看到的:

  1. class = require("myClass")
  2. --函数写在 table的括号外
  3. class:showName()
  4. --函数写在 table的括号内
  5. class.show(class)

编辑器中的效果如图-16所看到的:

图-16

-------------》require(“XXX”)  --  仅仅运行一次,避免了反复运行

1.4 完整代码

本案例中。完整代码例如以下所看到的:

  1. --[[lua不是一个面向对象的语言。可是他又有面向对象的思想
  2. lua中的面向对象是伪面向对象,伪面向对象就要用到table实现。
  3. 是table模拟了一个面向对象的编程。 table事实上也能够看做是一个对象,
  4. 和其它语言对象一样有个自身的标示(self)。具有自己的生命周期。]]
  5. --1.用table实现面向对象
  6. Accout = {balance = 0}
  7. functionAccout.count( v )
  8. print ("value is "..v)
  9. end
  10. --声明label对象(变量) accout
  11. accout = Accout
  12. --通过对象调用方法
  13. accout.count(1000)
  14. --2.通过 self 得到当前 lable 对象
  15. Accout = {balance = 10}
  16. --显示 传入 self
  17. functionAccout.count( self, v )
  18. self.balance = self.balance + v;
  19. print ("value is "..self.balance)
  20. end
  21. --声明label对象(变量) accout
  22. accout = Accout
  23. --通过对象调用方法, 显示的把 accout 这个 table 这个对象传入到函数 (显示的传入 self)
  24. accout.count(accout, 1000)
  25. --还可通过 : 调用的方式 隐试的传入 self 对象
  26. accout:count(2000)
  27. --3.通过 : 符号,实现声明函数时的 隐试參数 self
  28. Accout = { balance = 10}
  29. --通过 : 符号, 隐试 传入 self
  30. functionAccout:count( v )
  31. self.balance = self.balance + v;
  32. print ("value is "..self.balance)
  33. end
  34. --声明label对象(变量) accout
  35. accout = Accout
  36. --还可通过 : 调用的方式 隐试的传入 self 对象
  37. accout:count(2000)
  38. --4.通过require 返回对象, 调用该对象方法
  39. class = require("myClass")
  40. --函数写在 table的括号 外
  41. class:showName()
  42. --函数写在 table的括号 内
  43. class.show(class)
2、元方法与元表 元方法:就是两个 类型 变量之间进行操作的 函数 比如,1.数字的相加。它可能不过一个函数:1 + 1--->add(1,1)--->add函数就是用来计算两个数字间相加的结果de 2.table类型相加?--->Lua中不存在两个{} + {}的元方法。 元表(metatable):就是用来存放 元方法 的 table,是table提前定义的一系列操作。把两个table相加,那么Lua就会先去检查两个table是否有metatable,然后再检 查metatable中是否有__add方法。 假设有依照__add方法中的操作来运行,否则,报错。 比如,假设非要将两个table类型相加的话,直接执行必报错。 但Lua同意改动元表,例如以下所看到的: 一个元表,事实上就是一个table值,所以,我们仅仅须要新建一个table,加入元方法就可以。 比方加法运算的元方法就是:__add,这是Lua规定的。 仅仅要某个值的元表里含有__add这个元方法。那就能够使用+号进行运算。 例如以下代码:
  1. -- 创建一个元表
  2. local mt = {};
  3. mt.__add = function(t1, t2)
  4. print("两个table相加的结果就是...Good Good Study,Day Day Up!");
  5. end
  6. local t1 = {};
  7. local t2 = {};
  8. -- 给两个table设置新的元表
  9. setmetatable(t1, mt);
  10. setmetatable(t2, mt);
  11. -- 进行加法操作
  12. 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变量)。用来定义一些操作:

  1. -- 创建一个元表
  2. local mt = {};
  3. mt.__add = function(s1, s2)
  4. local result = "";
  5. if s1.sex == "boy" and s2.sex == "girl" then
  6. result = "青梅竹马";
  7. elseif s1.sex == "girl" and s2.sex == "girl" then
  8. result = "空对空";
  9. else
  10. result = "硬碰硬"
  11. end
  12. return result;
  13. end

事实上这和上一节的样例基本一样。仅仅是多说一次而已,使用方式例如以下:

  1. -- 创建两个table,能够想象成是两个类的对象
  2. local s1 = {
  3. name = "Hello",
  4. sex = "boy",
  5. };
  6. local s2 = {
  7. name = "Good",
  8. sex = "girl",
  9. };
  10. -- 给两个table设置新的元表
  11. setmetatable(s1, mt);
  12. setmetatable(s2, mt);
  13. -- 进行加法操作
  14. local result = s1 + s2;
  15. 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] end function Window.new(t) setmetatable(t,Window.mt) return t end --測试 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 = self return p end function People:groupUp() self.age = self.age + 1 print(self.age) end --測试 p1 = People:new() p1:growUp() --19 p2 = People:new() p2:growUp() --19 --[[执行结果能够看出:两个对象拥有的age成员是全然独立的。并且全部的有关People的方法都能够对外不可见,这样全然实现了面向对象中的类的封装--]] 继承: 继承是面向对象中不可缺少的一部分。依旧使用上例中的People,展示Lua中实现继承的方法。 创建一个People实例Man,再在Man上重写People的同名方法: Man = People:new() function Man:growUp() self.age = self.age + 1 print("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:19 person = Man:new() person:growUp() --Man‘s growUp:19

时间: 2024-12-08 13:40:26

cocos2d-Lua02Lua面向对象的相关文章

Cocos2d Lua 入门小例子 一个记忆力游戏

1.游戏说明 一个"记忆"类的比赛游戏.你和电脑对战,轮到谁的回合,谁翻两张牌,如果两张牌一样,就消掉这两张牌,得2分,可以继续翻牌,如果两张牌不一样,就换一个人.直到最后,看谁的得分高. 游戏设计思想可以看这篇文章<Cocos2d 游戏状态机> 2. Lua 简单面向对象 我们知道Lua是脚本语言,不是真正面向对象语言.但是面向对象好像能让代码结构更加合理,Javascript, Lua都可以模拟出面向对象.Lua面向对象还有超多种方式实现,这里当然不一一介绍.简单来看个

Cocos2d Lua 越来越小样本 内存游戏

1.游戏简介 一个"记忆"类的比赛游戏.你和电脑对战,轮到谁的回合,谁翻两张牌,假设两张牌一样.就消掉这两张牌,得2分,能够继续翻牌,假设两张牌不一样,就换一个人.直到最后.看谁的得分高. 游戏设计思想能够看这篇文章<Cocos2d 游戏状态机> 2. Lua 简单面向对象 我们知道Lua是脚本语言,不是真正面向对象语言.可是面向对象好像能让代码结构更加合理.Javascript, Lua都能够模拟出面向对象.Lua面向对象还有超多种方式实现,这里当然不一一介绍. 简单来看

python学习 面向对象封装

from collectoins import namedtuplePoint=namedtuple('point',['x','y'])t1=Point(1,2)print(t1.x)print(t1.y)没有方法的类属性不会发生变化    定义简单 不能改变面向对象封装私有属性!!!私有方法!!!用装饰器描述的几个方法@property !!!@classmethod!!@staticmethod! 封装:class Teacher:     def __init__(self,name,p

python—面向对象的封装

封装 私有属性 class Teacher: __identifier = 'Teacher' #私有静态属性 def __init__(self,name,pwd) self.name = name self.__pwd = pwd #私有属性 内部使用,外部不能使用 def pwd(self): print(self.__pwd) alex = Teacher('alex','3714') alex.pwd() class Teacher: __identifier = 'Teacher'

python学习_day26_面向对象之封装

1.私有属性 (1)动态属性 在python中用双下划线开头的方式将属性隐藏起来.类中所有双下划线开头的名称,如__x都会自动变形成:_类名__x的形式.这种自动变形的特点是: a.类中定义的__x只能在内部使用,如self.__x,引用的就是变形的结果.b.这种变形其实正是针对外部的变形,在外部是无法通过__x这个名字访问到的.c.在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,而父类中变形成了:_父类名__x,即双下滑线开头的属性在继承给子类时,子类是无法覆

python面向对象知识点疏理

面向对象技术简介 类: 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例.class 类变量:类变量在整个实例化的对象中是公用的.类变量定义在类中且在函数体之外.类变量通常不作为实例变量使用. 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据. 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖,也称为方法的重写. 实例变量:定义在方法中的变量,只作用于当前实例的类. 继承:即一个派生类(de

php学习笔记 面向对象中[接口]与[多态性]的应用

代码如下: <?php /* 接口技术 * * 接口是一种特殊的抽象类,抽象类又是一种特殊的类 * * 接口和抽象类是一样的作用 * * 因为在PHP是单继承的,如果使用抽象类,子类实现抽象类就不能再去继承其他的类了 * * 如果既想实现一些规范,又想继承其他类.就要使用接口. * * 接口和抽象类的对比 * * 1.作用相同,都不能创建对象,都需要子类去实现 * * 2.接口的声明和抽象类不一样 * * 3.接口被实现方式不一样 * * 4.接口中的所有方法必须是抽象方法,只能声明抽象方法(不

php面向对象

面向对象 什么是面向对象? 面向对象编程(Object Oriented Programming, OOP, 面向对象程序设计)是一种计算机编程架构,OOP的一条基本原则是计算机程 序是由单个能够起到子程序作用的单元或对象组合而成,OOP达到了软件工程的三个目标:重用性.灵活性和扩展性.为了实现整体 运算,每个对象都能够接收信息.处理数据和向其它对象发送信息. 什么是面向对象编程呢? 把每个独立的功能模块抽象成类形成 对象,由多个对象组成这个系统,这些对象之间都能够接收信息.处理数据和向其它对象

面向对象注意事项

在面向对象中,有实例变量和类变量,实例变量为类对象的实例成员,而类变量不仅类可以直接调用,而且类的对象也可以调用.类对象可以对实例变量进行添加.修改.删除操作等... 下面就用个示例来做参考: #!/usr/bin/env python # -*- coding:utf-8 -*- class PersonInfo(object): commity_data = 123 def __init__(self,name,age): self.name = name self.age = age de

java面向对象:面向对象的思想和概述

1:面向对象思想 面向对象是基于面向过程的编程思想. 面向过程:强调的是每一个功能的步骤 面向对象:强调的是对象,然后由对象去调用功能 2:面向对象的思想特点 A:是一种更符合我们思想习惯的思想 B:可以将复杂的事情简单化 C:将我们从执行者变成了指挥者 开发,设计,特征 面向对象开发 就是不断的创建对象,使用对象,指挥对象做事情. 面向对象设计 其实就是在管理和维护对象之间的关系. 面向对象特征 封装(encapsulation) 继承(inheritance) 多态(polymorphism