lua面向对象模拟简介

lua不是面向对象语言,但可以通过表(table)和元表(metatable)来模拟。table 是 lua 中唯一的一种数据结构,它可以用来描述原始的数组、符号表、集合、 记录、图、树等。每一个tabel都可以附加元表, 元表是带有索引集合的表,它可以改变被附加表的行为。因此,lua可以利用元表来模拟面向对象的行为。首先需要了解下面四个东东:
__index, __newindex, rawgetrawset

__index:是metatable的一个索引,它的值可以是表或者函数,它的作用是什么呢?举一个栗子:

1
2
3
4
5
6
local A = {};
local B = {x=10};
B.__index = B;
setmetatable(A, B);
 
print(A.x);

打印结果是10,它的查找过程是:首先在表A中查找x,没有找到,继续查找A的元表B,找到元表B的索引__index,此时__index的值是表B,表B是有元素x的,所以打印x的值10。简单总结一下查找表元素的过程:
1. 在表中查找,如果找到,返回该元素,找不到则继续2。
2. 判断该表是否有元表,如果没有元表,返回nil,有元表则继续3 。
3. 判断元表有没有__index,如果__index方法为nil,则返回nil;如果__index的值是一个table,则重复1、2、3;如果__index的值是一个function,则返回该函数的返回值。

__newindex:是metatable的一个索引,跟__index类似,它的值也可以是table或者function,当你给一个不存在的key赋值时,lua会在metatable里查找__newindex。看下面的例子:

1
2
3
4
5
6
7
8
9
10
local A = {};
local B = {x=10};
B.__newindex =  function (t, k,  v )
     rawset(t, k,  v );
end
setmetatable(A, B);
 
print(A.y);
A.y = 20;
print(A.y);

第一个print语句,打印是nil,第二个print语句打印出20。__newindex的值在这里是一个函数,有三个参数分别表示:表,键和值。

rawset:可以让你给表的索引赋值时绕过__newindex,如果你在上面的B.__newindex中直接使用t.k = v,会循环调用__newindex产生 stack overflow,rawset可以避免死循环。

rawget:可以绕过__index,如:
print(rawget(A, A.x));
此时打印nil,不会调用元表B的__index。

下面的demo使用lua简单模拟了面向对象的操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
local Animal = {
     name =  "animal" ;
}
 
function Animal:eat()
     print( "eat: " .. tostring(self.name) );
end
 
--new函数负责创建Animal对象。
function Animal:new(name)
     local obj = {};
 
     --访问表中不存在的k时会调用__index,此时self就是Animal
     self.__index = self;
 
     --对表中不存在的k进行赋值时会调用__newindex
     self.__newindex =  function (t, k,  v )
         --可以用来设置一些权限操作
         if (k ==  "sayhello" then
             print( "no premission" );
         else
             --t.k =  v ;会发生死循环,出现C stack overflow
             rawset(t ,k , v );
         end
     end
     setmetatable(obj, self);
     obj.name = name;
     return obj;
end
 
local Bird = {
     flySpeed = 10;
}
--继承Animal
setmetatable(Bird, Animal);
 
function Bird:new(name, flySpeed)
     local obj = Animal:new(name);
     obj.flySpeed = flySpeed;
     self.__index = self;
     setmetatable(obj, self)
     return obj;
end
 
function Bird:eat()
     print( "eat: " .. tostring(self.name) );
end
 
function Bird:fly()
     print( "name=" .. tostring(self.name) ..  "; flySpeed=" .. tostring(self.flySpeed) );
end
 
local anim = Animal:new( "animal" );
anim:eat();
anim.sayhello =  true ;
 
local bird = Bird:new( "bage" , 20);
bird:eat();
bird:fly();

运行结果:
eat: animal
no premission
eat: bage
name=bage; flySpeed=20



本文出自:http://codingnow.cn/language/1542.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值