4

特性を使用してゲーム オブジェクトを構築することが意味的に正しいかどうか疑問に思っています。私はこれを関係がある(オブジェクトにはコンポーネントがある) と見なしますが、コンポーネントはオブジェクトを構成するものと見なします。

例えば。あなたはゲームオブジェクトを持っています。GameObject は、それ自体ではほとんど何もしませんが、ゲームオブジェクトに混ぜると、追加のプロパティが与えられます。コンポーネントは、HealthComponent (ヘルスを持っている)、PhysicsComponent (物理をシミュレートする)、ClickableComponent (クリック可能) のいずれかです。

すべてのプロパティとメソッドが元のオブジェクトに追加されplayer.getHPplayer.getHealthComponent.getHP. 一方で、特性を使用するネーミングとセマンティクスは奇妙だと思います。trait HealthComponent extends GameObject- これは意味がありません。AHealthComponentは GameObject に属していますが、によって暗示されたis aextend関係を満たしていません。特性は通常、親クラスの特殊化されたバージョンとして扱われると仮定して正しいですか? もしそうなら、どのように私は上記のオブジェクトのような名前を付けますか?

4

3 に答える 3

4

@Moritzの答えを補足するために、スーパータイプから実装を継承せずに関連する動作をスタックすることも可能です。

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
于 2011-04-07T16:30:26.677 に答える
3

" trait HealthComponentextends - this doesn't make sense. AGameObject HealthComponent` は GameObject に属しています" -- 必要なのは自己型であり、ケーキ パターンに従って構築します。

だからあなたは持っています

trait HealthComponent {
   me: GameObject =>

   def inspect { me.querySomeGameObjectProperty }
}

val x = new GameObject with HealthComponent with ...

「トレイトは通常、その親クラスの特殊化されたバージョンとして扱われると仮定するのは正しいですか?」――そうは言わない。上記のようなボトムアップのアプローチを採用する場合、特性が一部の親のサブタイプであると考えるのではなく、その逆です (より大きなコンポーネントが特性によって構成され、特殊化されます)。

于 2011-04-07T01:12:20.693 に答える
3

特性を混合できる型を制限したい場合は、依存関係を自己型として表現できます。

trait Health { self: GameObject =>
 // ...
}

class Player extends GameObject with Movement with Health

この方法では、特性は拡張されませんGameObjectが、サブタイプの mixin としてのみ使用できますGameObject

Scala のケーキ パターンの理解とリンクされた記事も参照してください。

于 2011-04-07T01:04:31.057 に答える