Oop 当u_索引时,使表像值一样工作的优雅方式?
我的自制OO设计有一个特别的问题:Oop 当u_索引时,使表像值一样工作的优雅方式?,oop,inheritance,lua,Oop,Inheritance,Lua,我的自制OO设计有一个特别的问题: Entity = {} function Entity:new(o) o = o or {} return setmetatable(o, {__index = Entity}) end function Entity:init() end function Entity:think() end function Entity:spawn() --put in entity pool and begin drawing/logic self:i
Entity = {}
function Entity:new(o)
o = o or {}
return setmetatable(o, {__index = Entity})
end
function Entity:init() end
function Entity:think() end
function Entity:spawn()
--put in entity pool and begin drawing/logic
self:init()
end
Block = Entity:new{
x = 0,
y = 0,
color = {255, 255, 255, 255},
}
function Block:getPos()
return self.x, self.y
end
--setPos, getColor, setColor etc
function Block:init()
self:setColor(math.random(255), math.random(255), math.random(255))
end
a = Block:new()
a:spawn() --a new block with a random color
--a few seconds later...
b = Block:new()
b:spawn() --all blocks change to new color
color
表由所有原型和实例共享。如何使该表的行为类似于字符串:
a = {table}
b = a
print(b[1]) -->table
a[1] = "object"
print(a[1], b[1]) -->object, table
与对象相反:
a = {table}
b = a
print(b[1]) -->table
a[1] = "object"
print(a[1], b[1]) -->object, object
TL;DR:我需要创建一个新的数据类型。有三种方法可以解决您的问题:
实体.color
表,将其放入实体:新建()
函数中Entity.color
表替换为四个变量,这四个变量将表示其内容–Entity.colorred
,Entity.colorgreen
,Entity.colorblue
,Entity.coloralpha
self.color
表,而不是直接修改值self.color={red,green,blue,alpha}
而不是self.color[1]=红色;self.color[2]=绿色;self.color[3]=蓝色;self.color[4]=alpha
a = {table}
b = a
print(b[1]) -->table
a[1] = "object"
print(a[1], b[1]) -->object, table
您的示例涉及将变量赋值更改为复制值而不是引用。即使你能影响Lua的这种变化(你不能),这也是一个无法形容的可怕想法
颜色表由所有原型和实例共享
function Block:new()
local instance = { x = 0, y = 0 }
instance:setColor(math.random(255), math.random(255), math.random(255))
return setmetatable(instance, {__index = self})
end
因为您将它放在原型中(例如“类”),所以它相当于OOP语言中的静态成员,由所有实例共享。如果希望它是一个实例变量,那么它需要是实例构造的一部分,而不是类构造的一部分。您还需要对x
和y
执行相同的操作,否则它们也将被所有Block
实例共享
function Block:new()
local instance = { x = 0, y = 0 }
instance:setColor(math.random(255), math.random(255), math.random(255))
return setmetatable(instance, {__index = self})
end
您可以对构造函数进行一些增强,例如传入参数(例如初始化x
,y
,等等),但重要的是实例具有自己的状态
拥有
实体:spawn
在自身上简单地调用init是没有意义的。您显示的示例代码表明它实际上应该生成新实例,但实现并没有这样做。在:new()
中创建颜色表,而不是在调用:new()
时静态地创建。我更喜欢更灵活一点的东西您所说的“更灵活一点”是什么意思?我认为,在构造函数中创建实例属性是尽可能“灵活”的,其他任何东西都不那么灵活,只是耸耸肩。Zupoman在回答中介绍了可用的选项。通过创建新数组self.color={r,g,b,self.color[4]}
来实现Block:setColor(r,g,b)
,而不是将新值分配给color[1]
,color[2]
和color[3]
@EtanReisner你说得对,我想第三种选择可以合并为第一种。