在Lua中理解面向对象编程

5
我大部分的编程工作都是用Python完成的,我在大多数项目中使用面向对象编程(OOP)。最近,我开始研究Love2D游戏库和引擎。我设法配置了一些东西,然后考虑创建一个GameObject类。但是,怎么回事?Lua没有类!它有表、元表和其他类似的东西。即使我已经多次阅读了文档,我仍然很难理解这个问题。
请看以下示例:
catClass = {}
catClass.__index = catClass
catClass.type = "Cat"

function catClass.create(name)
    local obj = setmetatable({}, catClass)
    obj.name = name
    return obj
end

cat1 = catClass.create("Fluffy")
print(cat1.type)

cat2 = catClass.create("Meowth")

cat1.type = "Dog"

print(cat1.type)
print(cat2.type)
print(catClass.type)

这的输出如下所示:
Cat
Dog
Cat
Cat

我不理解的是将cat1.type更改为“Dog”为什么不会在cat2和catClass中引起相同的变化。设置元表是否会创建表的副本?谷歌没有提供有用的结果(很少有好的Lua解释)。
2个回答

7
当你对一个表进行索引并且键不存在时,Lua会查看该表是否存在元表。如果存在,则它将使用该元方法的__index键来重新索引您的键。
当你创建了cat1时,它继承了catClass元表。然后当你索引type时,它会发现cat1没有名为type的表条目,因此会查找元表来找到它。
然后你在cat1上设置type为Dog,这仅设置了cat1本身的表键,而不是元表。这就是为什么当你再次索引cat1的type时,你会得到Dog而不是Cat的原因。
如果你访问http://www.lua.org/,那里有Lua官方编写的编程指南的文档和一些旧版本的副本。

4
请参阅setmetatable文档 - 返回的表是第一个参数中指定的表。
这对于每次调用create都是不同的表(由于使用了{}),每个新表也与所使用的元表不同。没有进行复制,而是创建了一个的表,然后将其“链接”1到元表上。
因此,在上面的例子中有三个不同的表 - cat1(带有mt catClass),cat2(也带有mt catClass)和catClass本身。因此像上面那样修改cat1对其他两个表没有影响。

1请参阅Lua元表教程;在元表中使用的__index实际上模拟了JavaScript的[prototype]解析。

当您查找具有键的表时,无论键是什么,并且尚未为该键分配值.. Lua将在表的元表中查找__index键.. 如果__index包含一个表,则Lua将在属于__index的表中查找最初使用的键。

然而,__index对于分配一个新索引到其中一张表上没有影响 - 特定的表只是像平常一样被修改。(如果需要这种写入行为,请参阅教程中的__newindex的解释。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接