Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 当u_索引时,使表像值一样工作的优雅方式?_Oop_Inheritance_Lua - Fatal编程技术网

Oop 当u_索引时,使表像值一样工作的优雅方式?

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

我的自制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: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你说得对,我想第三种选择可以合并为第一种。