在Lua中,我们可以通过table+function来模拟实现类。

而要模拟出类,元表(metatable)和__index元方法是必不可少的。

为一个表设置元表的方法:

table = {}

metatable = {}

setmetatable(table, metatable)

或者

table = setmetatable({},{})

下面看一个简单的例子:

local t = {
k1 = "aaa"
}
local mt = {
k2 = "bbb",
__index = {
k3 = "ccc"
}
}
setmetatable(t, mt) print("k1:", t.k1, "k2:", t.k2, "k3:", t.k3)

输出:

k1:    aaa    k2:    nil    k3:    ccc

从例子可以看出,查找表元素时会从表的元表的__index键中查找。

查找一个表元素的规则如下:

1.在表中查找,如果找到,返回该元素;如果找不到,继续2
2.判断该表是否有元表,如果没有,返回nil;如果有,继续3
3.判断元表中是否有__index方法,
如果__index方法为nil,返回nil;
如果__index方法是一个表,则重复 1,2,3;
如果__index方法是一个函数,则返回该函数的返回值。 

除了有__index元方法外,还有__newindex,__add,__sub等很多原方法,可查看Lua文档

2.4 – Metatables and Metamethods

在了解了元表和元方法后,我们就可以模拟类的实现了。

local A = {
a1 = "this is a1",
a2 =
} function A.new()
local o = {}
setmetatable(o, A)
A.__index = A return o
end function A:Print()
print("This is A:Print ")
end local a = A.new()
a:Print()

输出结果:

This is A:Print 

以上就是一个类的简单实现方式,当然,我们也可以把它的实现封装到一个function中,这样会更方便我们类的创建和使用。

下面是cocos2d引擎中,lua类的实现,以供参考:

local setmetatableindex_
setmetatableindex_ = function(t, index)
if type(t) == "userdata" then
local peer = tolua.getpeer(t)
if not peer then
peer = {}
tolua.setpeer(t, peer)
end
setmetatableindex_(peer, index)
else
local mt = getmetatable(t)
if not mt then mt = {} end
if not mt.__index then
mt.__index = index
setmetatable(t, mt)
elseif mt.__index ~= index then
setmetatableindex_(mt, index)
end
end
end
setmetatableindex = setmetatableindex_ function class(classname, ...)
local cls = {__cname = classname} local supers = {...}
for _, super in ipairs(supers) do
local superType = type(super)
assert(superType == "nil" or superType == "table" or superType == "function",
string.format("class() - create class \"%s\" with invalid super class type \"%s\"",
classname, superType)) if superType == "function" then
assert(cls.__create == nil,
string.format("class() - create class \"%s\" with more than one creating function",
classname));
-- if super is function, set it to __create
cls.__create = super
elseif superType == "table" then
if super[".isclass"] then
-- super is native class
assert(cls.__create == nil,
string.format("class() - create class \"%s\" with more than one creating function or native class",
classname));
cls.__create = function() return super:create() end
else
-- super is pure lua class
cls.__supers = cls.__supers or {}
cls.__supers[#cls.__supers + ] = super
if not cls.super then
-- set first super pure lua class as class.super
cls.super = super
end
end
else
error(string.format("class() - create class \"%s\" with invalid super type",
classname), )
end
end cls.__index = cls
if not cls.__supers or #cls.__supers == then
setmetatable(cls, {__index = cls.super})
else
setmetatable(cls, {__index = function(_, key)
local supers = cls.__supers
for i = , #supers do
local super = supers[i]
if super[key] then return super[key] end
end
end})
end if not cls.ctor then
-- add default constructor
cls.ctor = function() end
end
cls.new = function(...)
local instance
if cls.__create then
instance = cls.__create(...)
else
instance = {}
end
setmetatableindex(instance, cls)
instance.class = cls
instance:ctor(...)
return instance
end
cls.create = function(_, ...)
return cls.new(...)
end return cls
end

Lua-面向对象中类的构造的更多相关文章

  1. Lua面向对象----类、继承、多继承、单例的实现

    (本文转载)学习之用,侵权立删! 原文地址   http://blog.csdn.net/y_23k_bug/article/details/19965877?utm_source=tuicool&a ...

  2. lua面向对象实现(实例化对象、继承、多态、多继承、单例模式)

    lua面向对象实现: 一个类就像是一个创建对象的模具.有些面向对象语言提供了类的概念,在这些语言中每个对象都是某个特定类的实例.lua则没有类的概念,每个对象只能自定义行为和形态.不过,要在lua中模 ...

  3. Step By Step(Lua面向对象)

    Step By Step(Lua面向对象) Lua中的table就是一种对象,但是如果直接使用仍然会存在大量的问题,见如下代码: 1 Account = {balance = 0}2 function ...

  4. BUAA面向对象设计与构造——第二单元总结

    BUAA面向对象设计与构造——第二单元总结 第一阶段:单部傻瓜电梯的调度 第二阶段:单部可捎带电梯的调度 (由于我第一次写的作业就是可捎带模式,第二次只是增加了负数楼层,修改了一部分参数,因此一起总结 ...

  5. BUAA面向对象设计与构造——第一单元总结

    BUAA面向对象设计与构造——第一单元总结 第一阶段:只支持一元多项式的表达式求导 1. 程序结构 由于是第一次接触面向对象的编程,加之题目要求不算复杂,我在第一次作业中并没有很好利用面向对象的特点, ...

  6. Lua面向对象之三:其它一些尝试

    1.尝试一:子类对象调用被覆盖了的父类函数 根据元表设置流程,我们只有将父类元表找到就能调用父类的方法了 ①在子类Circle中增加一个调用父类方法的函数 --调用父类被子类覆盖了的name方法 fu ...

  7. Lua面向对象之二:类继承

    1.类继承 ①代码 Sharp = { } --① 父类 function Sharp:new() local new_sharp = { } self.__index = self --②,self ...

  8. Lua面向对象之一:简单例子

    1.Lua面向对象实现步骤 ①创建一个全局表(称之为元表) ②设置这个元表的__index值(值通常为元表自己,这样就能通过__index查找到对应的属性和方法) __index 赋值其实是一个fun ...

  9. lua面向对象封装

    lua面向对象的一个封装,直接贴代码 --swfclass = {};local cs = {};function _class( child, base, ... )--    _.s( child ...

  10. 面向对象设计与构造:oo课程总结

    面向对象设计与构造:OO课程总结 第一部分:UML单元架构设计 第一次作业 UML图 MyUmlInteraction类实现接口方法,ClassUnit和InterfaceUnit管理UML图中的类和 ...

随机推荐

  1. 大叔最新课程~MVC核心技术剖析

    <MVC核心技术剖析介绍> 主讲:仓储大叔 时间:2016-12-04 20:30分 MVC各层分工 Http请求的过程 如何查找Action 如何渲染视图 ViewModel,DTO,D ...

  2. 美图WEB开放平台环境配置

    平台环境配置 1.1.设置crossdomain.xml 下载crossdomain.xml文件,把解压出来的crossdomain.xml文件放在您保存图片或图片来源的服务器根目录下,比如: htt ...

  3. Java 线程 — ThreadPoolExecutor

    线程池 线程池处理流程 核心线程池:创建新线程执行任务,需要获取全局锁 队列:将新来的任务加入队列 线程池:大于corePoolSize,并且队列已满,小于maxPoolSize,创建新的worker ...

  4. SSISDB8:使用SSISDB记录的消息Troubleshoot packages

    在执行Package时,SSISDB都会创建唯一的OperationID 和 ExecutionID,标识对package执行的操作和执行实例(Execution Instance),并记录opera ...

  5. DAC Usage4:从 Backup Package(.bacpac)还原DB

    使用DAC,能够将database的schema 和 data 从一个server 或 cloud 上复制到另外一个server上,存储schema 和 data的文件是 .bacpac 文件. 方法 ...

  6. margin-top失效的解决方法

    异常处理汇总-前端系列 http://www.cnblogs.com/dunitian/p/4523015.html 我的是属于这种情况 按照网上的说法,我就是这个现象了 两个层box1和box2,b ...

  7. 前端MVVM框架设计及实现(一)

    最近抽出点时间想弄个dom模块化的模板引擎,不过现在这种都是MVVM自带的,索性就想自己造轮子写一个简单的MVVM框架了 借鉴的自然还是从正美的avalon开始了,我记得还是去年6月写过一个系列的av ...

  8. 实现python中的map函数

    假设Python没有提供map()函数,自行编写my_map()函数实现与map()相同的功能.以下代码在Python 2.7.8中实现. 实现代码: def my_map(fun,num): i = ...

  9. JMM和happens-before原则

    JMM: Java Memory Model(Java内存模型),围绕着在并发过程中如何处理可见性.原子性.有序性这三个特性而建立的模型. 可见性: JMM提供了volatile变量定义.final. ...

  10. 数据可视化-EChart2.0使用总结2

    接上一篇博客,这篇博客主要讨论EChart里面的散点图.气泡图和雷达图.   4.散点图-Scatter Chart 适合场景:三维数据集,但是只有两个维度需要比较.比较的是X轴和Y轴的数据,第三个数 ...