lua中并没有提供原生类的定义,但lua中的表很灵活,可以使用表来模拟类的实现。
**如建一个猫咪类,有两个方法
1,偷鱼
2,吃鱼
1,有多少条鱼**
在java中的实现:
public class Cat {
//拥有参数
private int fish = 0;
//构造方法
public Cat(){
}
//偷取
public void stealFish(int amount){
fish += amount;
}
//吃掉
public void eatFish(int amount) {
if (amount > fish) {
return;
}else{
fish -= amount;
}
}
}
lua中先理清元表metatable与元方法__index的关系:
元表metatable就像是java一个类的父类,当然不完全相同。
1,访问一个表A的某个值时,表A会现在自身查找,找到返回。
2,如果找不到,则再到自己的元表B中找到元表B的__index方法执行,
如果__index指向nil,则返回nil
(是找到metatable的__index方法,并不是直接去查找metatable自身的值)。
3,如果__index指向了某个表C(或指向表B自身),就会到__index指向的表中查找表A中的值
,找到返回,并将值copy到表A(下次表A再访问这个值时就不再到metatable中查找了),
元表中不存在则返回nil。
元表的__index元方法也可以指向自己定义的方法,访问到__index时执行。
在lua中的实现:
--拥有参数
Cat = {fish= 0}
--构造方法
function Cat:new(instance) --说明0
instance = instance or {} --说明1
setmetatable(instance,self) --说明2
self.__index = self --说明3
return instance --说明4
end
--偷取
function Cat:stealFish(amount)
self.fish = self.fish + amount
end
--吃掉
function Cat:eatFish(amount)
if amount > self.fish then
error("not enough")
return
else
self.fish = self.fish - amount
end
end
实例化与调用
cat1 = Cat:new()
cat1:stealFish(3)
print(cat1.fish)
cat1:eatFish(1)
print(cat1.fish)
说明:
0,使用”:”new(),self指向Cat表。
1,新建一个空的表instance,instance将是从Cat类new出来的实例。
2,instance将Cat设为元表。
3,将Cat表的__index指定Cat表本身,这样访问Cat的属性和方法时,可被直接重定向到Cat表本身查找。
4,将instance返回。
也可以想象是cat1是一个空类,然后继承Cat类,类似地,lua模拟类继承可以通过设置metatable和__index完成。
模拟继承
有一个黑猫类,继承猫咪类,黑猫还能捉老鼠和吃老鼠,呵呵 - -,
BlackCat = Cat:new()
--属性
BlackCat.mouse = 0
--捉老鼠
function BlackCat:catchMouse(amount)
self.mouse = self.mouse + amount
end
--吃老鼠
function BlackCat:eatMouse(amount)
if amount > self.mouse then
print("not enough")
else
self.mouse = self.mouse - amount
end
end
--black1.的元表是BlackCat,而blackCat的元表是Cat,stealFish找到的还是Cat的方法
black1 = BlackCat:new()
black1:catchMouse(3)
print(black1.mouse)
black1:stealFish(4)
print(black1.fish)
模拟对类的封装:这是一类偷鱼可不让人知道的喵星人,啦
通过lua函数的局部变量模拟
function newCat()
--这里的self是自己定义的,觉得不好分清也可以取它名
local self = {fish = 0}
local function stealFish(amount)
self.fish = self.fish + amount
end
local function eatFish(amount)
self.fish = self.fish - amount
end
local function getFish(amount)
return self.fish
end
--以上属性与方法时局部的,所以只能在newCat方法内访问到
--所以再定义一个对外的实例来提供对私有的访问
instance = {
stealFish = stealFish,
eatFish = eatFish,
getFish = getFish
}
return instance
end