Tal vez podría envolver un Mapa [Manifiesto, Cualquiera] asegurando que los valores corresponden a las claves de manifiesto.
Posible boceto de eso. Primero un poco de ayuda
class Typed[A](value: A)(implicit val key: Manifest[A]) {
def toPair: (Manifest[_], Any) = (key, value)
}
object Typed {
implicit def toTyped[A: Manifest](a: A) = new Typed(a)
implicit def toTypable[A](a: A) = new {
def typedAs[T >: A : Manifest] = new Typed[T](a)(manifest[T])
}
}
entonces el envoltorio en sí (que no es un mapa)
class TypedMap private(val inner: Map[Manifest[_], Any]) {
def +[A](t: Typed[A]) = new TypedMap(inner + t.toPair)
def +[A : Manifest](a: A) = new TypedMap(inner + (manifest[A] -> a))
def -[A : Manifest]() = new TypedMap(inner - manifest[A])
def apply[A : Manifest]: A = inner(manifest[A]).asInstanceOf[A]
def get[A : Manifest]: Option[A] = inner.get(manifest[A]).map(_.asInstanceOf[A])
override def toString = inner.toString
override def equals(other: Any) = other match {
case that: TypedMap => this.inner == that.inner
case _ => false
}
override def hashCode = inner.hashCode
}
object TypedMap {
val empty = new TypedMap(Map())
def apply(items: Typed[_]*) = new TypedMap(Map(items.map(_.toPair) : _*))
}
Con eso se puede hacer
import Typed._
val repository = TypedMap("foo", 12, "bar".typedAs[Any])
repositorio: TypedMap = mapa (java .lang.String -> foo, Int -> 12, Any -> bar)
a recuperar elementos con
repository[String] // returns "foo"
repository.get[Any] // returns Some("bar")
Creo que el constructor privado debe garantizar que la _ asInstanceOf
es seguro. inner
puede dejarse en el público, ya que es inmutable. De esta forma, la rica interfaz de Map
estará disponible, pero lamentablemente no se creará otra TypedMap
.
¿Quiere decir que quiere que 'enemyDetailsStore' devuelva una cosa si' myEnemy' se extiende 'VerticalMover', y otra cosa si se extiende' RandomMover'? ¿Qué pasa si se extiende a los dos? –
Sí, eso es lo que quise decir. Pero estoy empezando a preguntarme por la cordura de mi idea. Tal vez debería tener alguna cadena clave incrustada en rasgos y usarla como la clave. Entonces, con la linealización del rasgo, el último rasgo primordial establecería el EnemyContainer en otras palabras, las texturas utilizadas para mostrar al enemigo. – vertti
La mayor parte del tiempo, el punto de un rasgo/interfaz es decir "Sé cómo hacer * X *", mientras que permite diferentes implementaciones de X. A falta de otros detalles, habría pensado que el diseño más natural sería sea para que el rasgo 'Moving 'tenga algún tipo de método' getMovingStrategy' o 'move' directamente sobre él, que puede implementarse en consecuencia en los subtrazos verticales y aleatorios del elemento motriz. –