特征可以用于在Scala中构建游戏组件系统吗?
我只是想知道使用traits构建游戏对象在语义上是否正确。一方面,我将其视为具有关系(对象具有组件),但另一方面,我将组件视为构成对象 比如说。你有一个游戏对象。游戏对象本身几乎什么都不做,但你混入其中的东西赋予了它额外的属性。组件可以是HealthComponent(具有健康)、PhysicComponent(模拟物理)、ClickableComponent(可以单击)特征可以用于在Scala中构建游戏组件系统吗?,scala,traits,Scala,Traits,我只是想知道使用traits构建游戏对象在语义上是否正确。一方面,我将其视为具有关系(对象具有组件),但另一方面,我将组件视为构成对象 比如说。你有一个游戏对象。游戏对象本身几乎什么都不做,但你混入其中的东西赋予了它额外的属性。组件可以是HealthComponent(具有健康)、PhysicComponent(模拟物理)、ClickableComponent(可以单击) 我喜欢使用traits的想法,因为所有属性和方法都添加到原始对象上,我可以执行player.getHP而不是player.g
我喜欢使用traits的想法,因为所有属性和方法都添加到原始对象上,我可以执行
player.getHP
而不是player.getHealthComponent.getHP
。另一方面,我发现使用traits的命名和语义很奇怪<代码>特征健康组件扩展游戏对象-这没有意义。HealthComponent
属于游戏对象,它不满足extend
所暗示的关系。我假设特质通常被视为其父类的特殊版本,对吗?如果是这样,我将如何命名上述对象?如果您想限制您的特质可以混合的类型,您可以将依赖性表示为自我类型:
trait Health { self: GameObject =>
// ...
}
class Player extends GameObject with Movement with Health
这样你的特质就不会扩展到GameObject
,而只能作为GameObject
的子类型的混入
另请参阅和链接文章。“trait HealthComponent
扩展了游戏对象-这没有意义。
HealthComponent`属于游戏对象”--您需要的是自我类型,并根据蛋糕模式进行构建:
trait HealthComponent {
me: GameObject =>
def inspect { me.querySomeGameObjectProperty }
}
val x = new GameObject with HealthComponent with ...
“我假设特质通常被视为其父类的特殊版本,对吗?”——我不会这么说。如果您采用上述自底向上的方法,您不会认为trait是某些父类的子类型,相反(更大的组件由trait组成并由trait专门化)作为补充,也可以在不继承超级类型实现的情况下堆叠相关行为:
trait HasFoo { def foo: Unit }
class GameObject extends HasFoo {
def foo = {}
}
trait Health extends HasFoo {
self: GameObject =>
abstract override def foo = {
println("health foo")
super.foo
}
}
trait Dog extends HasFoo {
self: GameObject =>
abstract override def foo = {
println("dog foo")
super.foo
}
}
scala> val g = new GameObject with Health with Dog
g: GameObject with Health with Dog = $anon$1@33b7b32c
scala> g.foo
dog foo
health foo
那更好,谢谢。但是如果
Player
和Movement
都定义了methodfoo
,我怎么才能让它们都被调用(类似于super
)呢?你不能。可以重写方法,但不能调用超级类型的实现。如果需要这样做,您必须使用继承。您可以调用超级类型的实现,而无需使用抽象重写从超级类型继承。但是,您的traits必须继承自声明foo
方法的公共接口。我将在回答中演示这一点。