我的游戏开发框架有一个Point
类(存储x
,y
坐标和其他有用的东西)。我的游戏对象具有@position
属性,即Point
个实例。修改@position
后,游戏对象将被绘制到其他地方。
我的问题是:
@someSprite.position = Point.new(100,100)
temp = @someSprite.position
temp.x = 500
temp
成为@someSprite.position
的引用。修改它也会改变精灵的位置。这是我不想要的。我希望temp
成为另一个实例。
我做不到这样的事情:
temp = @someSprite.position.clone
由于框架中的另一个细节:Point
是observable。 @someSprite
正在观察自己的属性@someSprite.position
。
如果我使用clone
,那么temp
也会克隆观察者注册表。当temp
的状态发生变化时,@someSprite
会被通知,造成混乱。
然后就可以做到这一点:
temp = @someSprite.position.clone
temp.remove_observer(@someSprite)
但这感觉不切实际和黑客。
另一种方法是:
temp = Point.new(@someSprite.position)
我为Point
创建一个构造函数,它从另一个Point
获取值(不复制观察者注册表)。这听起来像目前为止最好的方法,但我想要实现的是
temp = @someSprite.position
可以这样做吗?在这种情况下,我可以覆盖赋值运算符的行为吗?
答案 0 :(得分:1)
您解释了无法使用clone
的原因,但这并不意味着您无法覆盖clone
或创建duplicate
等新方法。
所以在你的Point类上只需定义:
def duplicate
Point.new(x,y)
end
然后你可以这样做:
temp = @someSprite.position.duplicate
答案 1 :(得分:1)
我假设你在attr_reader
上使用@position
来定义精灵的position
方法。但您也可以定义自己的getter。在这种情况下,我建议你为该职位创建一个明确的getter:
class Sprite
def position
return Point.new(@position.x, @position.y)
end
end
你想要在对象内部引用精灵的位置而不是它的值的副本是非常罕见的;暴露一个班级的私人成员实际上是非常危险的。
答案 2 :(得分:0)
Ruby是开源的,所以当然,您可以使用语言C
覆盖一些知识操作。但我不建议。