简单的Lua游戏,简单的类似:
creature = class({
name = "MONSTER BADDY!",
stats = { power = 10, agility = 10, endurance = 10, filters = {} },
other_things = ...
})
creatureA = creature.new()
creatureB = creature.new()
creatureA.name = "Frank"
creatureB.name = "Zappa"
creatureA.stats.agility = 20
creatureB.stats.power = 12
- 等等等等等等
非表值是每个实例的个别值,但表值是 在所有实例之间共享,如果我在一个实例中修改stats.X值, 所有其他实例都看到相同的统计表。
Q1:我的OO实施是否有缺陷?我尝试了LOOP并发生了同样的结果, 我的逻辑中有一个根本的缺陷吗?
Q2:你如何让每个生物实例拥有自己的统计表(和子表)?
PS。我不能展平我的类表,因为它比示例更复杂,并且使用这种嵌套的表实现简化了代码的其他部分。
答案 0 :(得分:3)
它的工作方式与此类似,因为类实例在其metatable中将类表设置为__index
(好吧,大多数实现以这种方式工作)
因此,如果您访问creatureA.stats
(并且在stats
上找不到creatureA
,则会落在__index
),则会返回creature.stats
。
也许你应该阅读Lua 5.1 Reference Manual: Metatables
您将无法在类的表构造函数中声明每个实例变量(除非您将类表中的所有内容深度复制到实例,这将非常昂贵)
您必须在类实现使用的任何初始化函数中执行此操作:
creature = class
{
__init = function(self, ...)
self.stats = {power = 10, agility = 10, endurance = 10, filters = {}}
end,
}
答案 1 :(得分:3)
class
不是Lua中的标准函数。你不是说你是从罗伯托借来的,是自己的,还是什么的。但我的猜测是你要更改new
方法,以便它对原型进行深层复制而不是浅层复制:
function deep_copy(v)
if type(v) == 'table' then
local u = { }
for k, v in pairs(v) do
u[k] = v
end
setmetatable(u, getmetatable(v))
return u
else
return v
end
end
(警告:我没有尝试编译此代码,更不用说运行它了。)
答案 2 :(得分:0)
创建新的creature
时,如果您不希望它被共享,您可以随时为其创建一个新的stats
表。
creature = class({
name = "MONSTER BADDY!",
stats = stats.new({ power = 10, agility = 10, endurance = 10, filters = {} }),
other_things = ...
})
权力,敏捷性等将作为stats
的构造函数中的参数传递。
答案 3 :(得分:0)
你的名为 class 的功能看起来很可疑。我会选择最简单的代码。这是一个怪物类文件。没有什么花哨的,有些人会说它缺乏一些毛病,但至少我也可以在下周自己阅读这些代码。
-- Class object
monster = {}
monster.__index = monster
-- Class methods
function monster.new(name)
local o = {}
o.name = name
o.stats = {power = 10, agility = 10, endurance = 10, filters = {}}
setmetatable(o, monster)
return o
end
function monster:shout()
print('Aaaaaaa! My name is ' .. self.name .. '!')
end
这是输出:
> lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> require 'monster'
> m = monster.new('Katla')
> m:shout()
Aaaaaaa! My name is Katla!