本文介绍一下lua面向对象的实现方法,只摘取最有用最核心的部分进行介绍,因为之前也看过一些面向对象的实现,功能很完善,同时也略显复杂。本文会尽量用最简洁的方式把lua面向对象描述清楚,一看便知。
1.LUA元表
本文使用lua元表实现面向对象,所以先要介绍下lua的元表。元表中有很多的元方法,这里不会全部介绍,仅仅只介绍__index这个元方法。
1.1 __index
直接说明__index的作用:lua中当用下标访问一个表的成员时, 分下面几个步骤:
(1) 根据key值查找表A成员a, 若无则下一步
(2) 判断表A是否有元表B, 若无则返回nil, 有则下一步
(3) 若元表B有__index成员则: 分两步走
a. __index是一个表: 在__index表中查找a
b. __index是一个函数: 返回__index的返回值
什么意思呢?看下面的例子:
`
--定义一个表
local mytable = {a = "1"};
--打印看看, 这里'mytable.b == nil'
print(mytable.a);
print(mytable.b);
--再定义一个元表
local mymetabl = {__index = {b = "2"}};
--将这个元表设置为'mytable'的元表
setmetatable(mytable, mymetatable);
--再打印看看, 发现这里'mytable.b == "2"'
print(mytable.a);
print(mytable.b);
`
看出来了吗,在mytable中索引b时, 没有找到, 然后判断是否有元表, 发现有元表就在元表中索引b。这是__index为一个表的情况,还有一种情况__index为一个函数,这里就不说了。
#2. 简单面向对象 说明直接写在注释里面, 有两个.lua文件, 'class.lua'是类的实现,'main.lua'是测试类的功能. class.lua:
```
print("class.lua")
classList = {};
class = {};
--定义一个类
class.define = function(self, className, template, baseClass)
print("class.define: className = ", className);
local curClass = template or {};
curClass.className = className;
if baseClass then
setmetatable(curClass, {__index = baseClass});
curClass.parent = baseClass;
end
classList[className] = curClass;
end
--创建一个类的实例
class.new = function(self, className)
print("class.new: className = ", className);
local instance = {};
if classList[className] then
setmetatable(instance, {__index = classList[className]});
end
return instance;
end
function getClassByName(className)
print("getClassByName:", className);
return classList[className] or nil;
end
return class;
```
main.lua
```
--应用模块
local class = require(".\class");
require('mod1');
--定义基类
class:define("baseClass", {
name = "baseClass",
id = 0,
getId = function(self)
print("baseClass.id = ", self.id);
end,
});
--定义子类1
class:define("childClass1", {
id = 1,
},
getClassByName("baseClass")
);
--定义子类2
class:define("childClass2", {
id = 2,
getId = function(self)
print("childClass2.id = ", self.id);
end,
},
getClassByName("baseClass")
);
--子类1的一个实例
local insChild1 = class:new("childClass1");
--子类2的一个实例
local insChild2 = class:new("childClass2");
print("end:");
var_dump(classList);
--调用到了基类的'getId'方法
insChild1:getId();
--调用子类2自己的'getId'方法
insChild2:getId();
--调用子类2的父类的'getId'方法
insChild2.parent:getId();
```