浅谈Lua面向对象的实现
来源:互联网 发布:深圳平湖淘宝客服招聘 编辑:程序博客网 时间:2024/04/30 10:02
一:lua的类实现
有时候有些lua对象(其实就是个table)并不是全局的,需要创建多个,这个时候就得模拟类的机制
-------------------------------------------------------------------
-- 拷贝表数据
-- @param b : 原始表
-- @param a : 新表
-------------------------------------------------------------------
-- lua的表默认是引用的,例如a={1,2} b=a b[1]=2 此时a[1]也会等于2
-- 这个函数支持将表真正的拷贝一份,各自可以独立修改
-- 同时支持嵌套的表拷贝,例如a={1,2,{3,4,5}} copy_table(b,a)
-------------------------------------------------------------------
function copy_table(a,b)
--a = {} 这里不能将a表置为空表,因为这样做会导致a表内存地址的改变
for key,value in b do
if type(value)=='table' then
a[key] = {}
copy_table(a[key],value)
else
a[key]=value
end
end
end
-- 公共基类
Object = {}
-- 成员函数形式的new
function Object:new(o)
o = o or {}
-- Table型数据默认是引用的,所以需要从基类拷贝一份,否则很容易出现莫名奇妙的错误
for key,value in self do
if type(value)=='table' then
if o[key]==nil or o[key]==value then
o[key]={}
copy_table(o[key],value)
end
end
end
setmetatable(o,{__index = self})
return o
end
-- 操作符形式的new
function new(type,param)
param = param or {}
return type:new(param)
end
--原型基类
PrototypeObject = {}
--克隆方法
function PrototypeObject:new(o)
o = o or {}
DoClone(o,self)
return o
end
--克隆方法
--@param destObject 目标对象
--@param srcObject 源对象
function DoClone(destObject,srcObject)
for key,value in srcObject do
--目标对象有的元素不拷贝
--指向目标对象也不拷贝,防止循环引用拷贝出错
if destObject[key] == nil and value ~= destObject then
if type(value)=='table' then
destObject[key] = {}
DoClone(destObject[key],value)
else
destObject[key]=value
end
end
end
end
--继承很简单
local A = Object:new()
local B = A:new()--B即使继承A
--lua面向对象的实现主要是利用了Lua表中__index的特性
lua查找表元素的时候遵循下面三个步骤
1.在表中查找,如果找到,返回该元素,找不到则继续
2.判断该表是否有元表,如果没有元表,返回nil,有元表则继续
3.判断元表有没有__index方法,如果__index方法为nil,则返回nil;如果__index方法是一个表,则重复1、2、3;如果__index方法是一个函数,则返回该函数的返回值
二:lua中对方法的访问方式,通过.与:的区别
t = {x = 1}
t.foo = function(t)
print(t.x);
end
local a = {x = 2};
print(t.foo(a), t:foo(a));
输出:
2
1
nil
表明用:访问时传入的第一个参数是自己,即self,
其实有时候有疑问,当我们写一个函数的时可以写成
t.foo = function(t)
/////
end
也可以写成
funtiong t:foo()
///
end
这两种写法都没有关系,只是Lua的语法,给Lua的表中添加一个成员
当我们将其模拟成类的时候,会写成第二种,看成表的时候会写成第一种
t = Object:new{x = 1}
function t:foo(a)
print(a.x);
end
local a = {x = 2};
print(t.foo(self,a), t:foo(a));
输出:
2
2
nil
若我们将t.foo(self,a)中的self去除,就会说a is a nil
通过上面我们可以看出函数写的方式不管你是.还是:都没有影响,只用当你访问的时候是用.还是用:才决定是否默认传入了self,
其实这也是模拟了c++的方式,函数第一个参数默认传入的是self,这个步骤只是编译器帮你做了,自己不知道而已
有时候有些lua对象(其实就是个table)并不是全局的,需要创建多个,这个时候就得模拟类的机制
-------------------------------------------------------------------
-- 拷贝表数据
-- @param b : 原始表
-- @param a : 新表
-------------------------------------------------------------------
-- lua的表默认是引用的,例如a={1,2} b=a b[1]=2 此时a[1]也会等于2
-- 这个函数支持将表真正的拷贝一份,各自可以独立修改
-- 同时支持嵌套的表拷贝,例如a={1,2,{3,4,5}} copy_table(b,a)
-------------------------------------------------------------------
function copy_table(a,b)
--a = {} 这里不能将a表置为空表,因为这样做会导致a表内存地址的改变
for key,value in b do
if type(value)=='table' then
a[key] = {}
copy_table(a[key],value)
else
a[key]=value
end
end
end
-- 公共基类
Object = {}
-- 成员函数形式的new
function Object:new(o)
o = o or {}
-- Table型数据默认是引用的,所以需要从基类拷贝一份,否则很容易出现莫名奇妙的错误
for key,value in self do
if type(value)=='table' then
if o[key]==nil or o[key]==value then
o[key]={}
copy_table(o[key],value)
end
end
end
setmetatable(o,{__index = self})
return o
end
-- 操作符形式的new
function new(type,param)
param = param or {}
return type:new(param)
end
--原型基类
PrototypeObject = {}
--克隆方法
function PrototypeObject:new(o)
o = o or {}
DoClone(o,self)
return o
end
--克隆方法
--@param destObject 目标对象
--@param srcObject 源对象
function DoClone(destObject,srcObject)
for key,value in srcObject do
--目标对象有的元素不拷贝
--指向目标对象也不拷贝,防止循环引用拷贝出错
if destObject[key] == nil and value ~= destObject then
if type(value)=='table' then
destObject[key] = {}
DoClone(destObject[key],value)
else
destObject[key]=value
end
end
end
end
--继承很简单
local A = Object:new()
local B = A:new()--B即使继承A
--lua面向对象的实现主要是利用了Lua表中__index的特性
lua查找表元素的时候遵循下面三个步骤
1.在表中查找,如果找到,返回该元素,找不到则继续
2.判断该表是否有元表,如果没有元表,返回nil,有元表则继续
3.判断元表有没有__index方法,如果__index方法为nil,则返回nil;如果__index方法是一个表,则重复1、2、3;如果__index方法是一个函数,则返回该函数的返回值
二:lua中对方法的访问方式,通过.与:的区别
t = {x = 1}
t.foo = function(t)
print(t.x);
end
local a = {x = 2};
print(t.foo(a), t:foo(a));
输出:
2
1
nil
表明用:访问时传入的第一个参数是自己,即self,
其实有时候有疑问,当我们写一个函数的时可以写成
t.foo = function(t)
/////
end
也可以写成
funtiong t:foo()
///
end
这两种写法都没有关系,只是Lua的语法,给Lua的表中添加一个成员
当我们将其模拟成类的时候,会写成第二种,看成表的时候会写成第一种
t = Object:new{x = 1}
function t:foo(a)
print(a.x);
end
local a = {x = 2};
print(t.foo(self,a), t:foo(a));
输出:
2
2
nil
若我们将t.foo(self,a)中的self去除,就会说a is a nil
通过上面我们可以看出函数写的方式不管你是.还是:都没有影响,只用当你访问的时候是用.还是用:才决定是否默认传入了self,
其实这也是模拟了c++的方式,函数第一个参数默认传入的是self,这个步骤只是编译器帮你做了,自己不知道而已
0 0
- 浅谈Lua面向对象的实现
- Lua面向对象的实现
- lua的面向对象实现
- Lua 面向对象实现
- lua实现面向对象
- lua实现面向对象
- lua实现面向对象
- 【Lua】面向对象实现
- Lua面向对象实现
- Lua面向对象实现
- lua 实现面向对象
- lua实现面向对象的特性
- lua实现面向对象的特性
- lua实现面向对象的特性
- lua实现面向对象的特性
- Lua语言中面向对象的实现
- lua面向对象是怎么实现的
- lua面向对象是怎么实现的
- 给Centos的terminal设置Solarized主题
- 时间管理--简记
- iOS 跳转页面tab bar闪动
- 简述Android启动模式
- java数据类型
- 浅谈Lua面向对象的实现
- 图的m着色问题pascal程序
- .NET学习笔记(3)——深入.net平台和C#编程
- 网络流24题4 魔术球问题 ssl 2604 code[vs] 1234
- 深入理解Activity启动流程(三)–Activity启动的详细流程1
- scala 学习(一)——for循环
- Java实现Html转PDF
- FFmpeg播放视频类,可复用
- UVa10237 Bishops