版权声明:本文为博主原创文章,转载请注明出处。

  面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物。 
早期的计算机编程是基于面向过程的方法,通过设计一个算法就可以解决当时的问题。随着计算机技术的不断提高,计算机被用于解决越来越复杂的问题。面向过程式的编程思想很难良好的解决这些复杂的问题,通过面向对象的方法,更利于用人理解的方式对复杂系统进行分析、设计与编程。同时,面向对象能有效提高编程的效率,通过封装技术,消息机制可以像搭积木的一样快速开发出一个全新的系统。 
  但是随着软件行业的飞速发展,渐渐的有人开始觉得面向对象编程让代码显的非常复杂,工程庞大。开始有一部分人回归到了面向过程编程,开始运用面向对象和面向过程结合的方式进行开发。 
  面向对象最主要的两个概念就是对象和类,能够充分理解这两个概念的人自然也很容易理解面向对象的编程思想。 
  所谓对象,就是用来描述客观存在的一个实体,它是构成系统的一个基本单位。一个对象应该由若干属性组成,这些属性用于描述这个实体的信息,比如某个人的名字。另外还应该包含一些方法,用于描述实体的动作,比如某个人吃饭的过程。 
  类是具有相同属性和方法的所有对象实体的抽象,类的内部为这些对象提供了统一的抽象描述。比如所有人都有名字,那么“人”这个类就应该包含一个属性叫做人名。所有的人都有这个属性,类的方法也是一样的道理。 
  Lua语言中没有类的定义,也不能定义类,但是我们可以使用table来模仿对象,如下:

     --  定义一个表来模拟对象,将id和name看成的它的属性
local person = {id = , name = "yzn",}
-- 给对象添加方法
function person.sayHello(self)
print("你好,我的名字是" .. self.name)
end
- - 访问属性
print(person.id)
- - 调用方法
person:sayHello()

  接下来我们来访问person的属性和调用sayHello方法。发现无论是语法还是效果上面都和Java等其它语言操作对象的方式极其类似。但是值得注意的是我在调用方法的时候person后面用的是冒号(:)来调用sayHello方法,而不是使用一点。这其实是Lua的一个语法糖衣,使用冒号调用的时候Lua会自动将调用者当成函数的第一个参数的实参传递到函数内部去。所以我就没有传递参数给sayHello的self参数那边。 
  也是就是:

 person:sayHello()

  与

 person.sayHello(person)

  是一样的效果,冒号和点号只是用来决定是否需要手动传递第一个参数而已。 
  现在我们来看下类是如何模拟出来的:

     -- 定义一个Person表,当成类。添加一个属性id,和一个方法toString
Person = {
id = "",
toString = function(p)
print("id = ", p.id)
end
} -- 给Person再添加一个new函数,用于实例化对象。
function Person.new()
-- 定义一个表,当成被实例化出来的对象
obj = {}
-- 设置表的元表
setmetatable(obj, Person)
-- 设置__index方法为自身
Person.__index = Person
-- 返回创建的实例对象
return obj
end -- 调用new函数实例化对象
local obj = Person.new()
-- 访问属性
print("obj.id = ", obj.id)
-- 调用方法
obj:toString()

  其实Lua中就是通过设置元表的方式来实现继承关系的,这里所谓的类和对象,其实就是让一个obj表继承Person这个表(设置obj的元表为Person)。然后设置元方法__index为Person,这样我们访问obj的id属性时,它在自己的表中没有找到就会调用元方法__index去元表里面找,也就是去Person里面去找,然后返回了Person的id属性的值,方法调用也是一样的。如果没有设置__index,那么没有找到会直接返回nil。 
  元表和元方法,是Lua内置的一些操作。Lua的每个变量都具有一张元表,我们可以通过getmetatable(var)函数得到对象的元表。而对于setmetatable()方法,设置元表只能针对于table类型的变量。要修改设置其他值的元表,我们需要通过C的API来实现。 
  table默认是没有设置其元表的,我们可以通过以下代码进行验证:

     local tab1 = {, , }
print(getmetatable(tab1)) -- 输出nil

  其实所谓的元表就是一个普通的表,我们现在来设置下tab1的元表:

     local tab1  = {, , }
-- 定义一个普通的空表作为元表
local mt = {}
setmetatable(tab1, mt)
print(getmetatable(tab1)) -- 输出table

  我们甚至可以给上面的mt添加一个项,然后获取出tab1的元表进行dump查看是否就是mt:

     local tab1  = {, , }
-- 定义一个普通的空表作为元表
local mt = { id = , }
setmetatable(tab1, mt)
dump(getmetatable(tab1)) -- 输出表里面的所有内容

  我在quick-player模拟器上面运行,控制台窗口输入的内容如下图所示。

  我们可以清晰的看到确实是设置元表成功了。 
  接下来我们来重载Lua的运算符。Lua的运算符是通过元方法进行计算的,元方法分为算数元方法和关系元方法。Lua的元方法都是以双下划线开头的,比如上面提到的__index等。 
所谓的算数元方法就是在进行算数运算的时候会被调用的方法。比如进行加法的__add和减法的__sub。我们这里以加法运算符为例,在进行重载加法运算符(+)之前,对两个table进行相加肯定活报错。所以,我们现在先对加法进行重载,代码如下:

     local tab1  = {"a", "b", "c"}
-- 定义一个普通的空表作为元表
local mt = {}
-- 设置tab1的元表为mt
setmetatable(tab1, mt)
-- 重写元方法
mt.__add = function(t1, t2)
local t = {} for i, v in ipairs(t1) do
table.insert(t, v)
end for i, v in ipairs(t2) do
table.insert(t, v)
end return t
end -- 定义另一个table
local tab2 = {"d", "e",} -- 对tab进行加法运算,会触发__add元方法
local tab3 = tab1 + tab2
-- 打印计算后的结果
dump(tab3)

  运行后看到打印的tab3的值如下所示:

  可见我们重载是成功了,其他的元方法重载和加法的基本一致。

【quick-cocos2d-x】Lua 面向对象(OOP)编程与元表元方法的更多相关文章

  1. PHP面向对象(OOP)编程入门教程

    面向对象编程(OOP)是我们编程的一项基本技能,PHP5对OOP提供了良好的支持.如何使用OOP的思想来进行PHP的高级编程,对于提高 PHP编程能力和规划好Web开发构架都是非常有意义的.下面我们就 ...

  2. 【PHP面向对象(OOP)编程入门教程】1.什么是面向对象?

    面向对象编程(Object Oriented Programming, OOP, 面向对象程序设计)是一种计算机编程架构,OOP的一条基本原则是计算机程序是由单个能够起到子程序作用的单元或对象组合而成 ...

  3. php面向对象(OOP)编程完全教程

    摘自:http://www.php-note.com/article/detail/41 面向对象编程(OOP)是我们编程的一项基本技能,PHP5对OOP提供了良好的支持.如何使用OOP的思想来进行P ...

  4. PHP面向对象(OOP)编程入门教程链接

    PHP官方学习OOP: http://php.net/manual/zh/oop5.intro.php 从其他博主学习:(以下链接来源: http://blog.snsgou.com/post-41. ...

  5. 【PHP面向对象(OOP)编程入门教程】2.什么是类,什么是对象,类和对象这间的关系

    类的概念:类是具有相同属性和服务的一组对象的集合.它为属于该类的所有对象提供了统一的抽象描述,其内部包括属性和服务两个主要部分.在面向对象的编程语言中,类是一个独立的程序单位,它应该有一个类名并包括属 ...

  6. lua中 table 重构index/pairs元方法优化table内存占用

    转载请标明出处http://www.cnblogs.com/zblade/ lua作为游戏的热更新首选的脚本,其优势不再过多的赘述.今天,我主要写一下如何重写lua中的元方法,通过自己的重写来实现对l ...

  7. PHP面向对象(OOP)编程入门教程————如何实例化对象?

    我们上面说过面向对象程序的单位就是对象,但对象又是通过类的实例化出来的,既然我们类会声明了,下一步就是实例化对象了. 当定义好类后,我们使用new关键字来生成一个对象. $对象名称 = new 类名称 ...

  8. js面向对象oop编程

    理解对象 对象这个词如雷贯耳,同样出名的一句话:XXX语言中一切皆为对象! 对象究竟是什么?什么叫面向对象编程? 对象(object),台湾译作物件,是面向对象(Object Oriented)中的术 ...

  9. 【PHP面向对象(OOP)编程入门教程】23.自动加载类 __autoload()函数

    很多开发者写面向对象的应用程序时,对每个类的定义建立一个 PHP 源文件.一个很大的烦恼是不得不在每个脚本(每个类一个文件)开头写一个长长的包含文件的列表. 在软件开发的系统中,不可能把所有的类都写在 ...

随机推荐

  1. Linux系统文件访问控制列表

    linux系统中的RWX权限.特殊权限.隐藏权限都是对某一类用户设置的, 而如果希望对某个指定的用户进行单独的权限设置的话就需要用到文件的 访问控制权限了. 我们可以对普通文件或目录进行设置ACL,通 ...

  2. WPF如何用TreeView制作好友列表、播放列表

    WPF如何用TreeView制作好友列表.播放列表 前言 TreeView这个控件对于我来说是用得比较多的,以前做的小聊天软件(好友列表).音乐播放器(播放列表).类库展示器(树形类结构)等都用的是T ...

  3. Effective C++条款01: 视C++为一个语言联邦

    一开始C++定义为:C with Classes. 如今的C++已经是一个多重范型编程语言,可以把C++视为有四个次语言组成的联邦语言. C.C++任然以C为基础.区块.语句.预处理.内置语言类型.数 ...

  4. WEB前端介绍

    1.WEB前端是神马 Web前端开发是从网页制作演变而来的,名称上有很明显的时代特征.在互联网的演化进程中,网页制作是Web1.0时代的产物,那时网站的主要内容都是静态的,用户使用网站的行为也以浏览为 ...

  5. android 从服务器上获取APK下载安装

    简单的为新手做个分享.  网上有些资料,不过都是很零散,或是很乱的,有的人说看不懂. 一直有新手说 做到服务器更新APK时没有思路,这里做个简单的分享,希望有不同思路的可以讨论.  下面做个很简单的读 ...

  6. Ubuntu下安装Git以及Git帮助手册【转】

    转自:http://milkythinking.com/blog/2011/04/17/install_git_and_manual/ Git简介 Git是一个分布式版本控制系统,对应的是SVN.CV ...

  7. Android控件系列之CheckBox

    学习目的: 1.掌握在Android中如何建立CheckBox 2.掌握CheckBox的常用属性 3.掌握CheckBox选中状态变换的事件(监听器) CheckBox简介: CheckBox和Bu ...

  8. 推荐个Java代码质量检测的利器 —— FindBugs

    一.下载 插件的下载地址(sourceforge):FindBugs-Eclipse插件 二.安装 Eclipse插件的安装,就不多说了. 三.使用 1.找一个Project,选中它(也可以针对某个P ...

  9. Android实现自定义字体

    介绍 最近在看开源项目的时候,发现里面涉及到了自定义字体,虽然自己目前还用不到,但是动手demo笔记记录一下还是有必要的,没准哪天需要到这个功能. 原理 1.其实实现起来非常简单,主要是用到了Type ...

  10. easyui validatebox 验证集合

    <html xmlns="http://www.w3.org/1999/xhtml"> <head> <script src="easyui ...