Проблема «MyType»: нужно ли мне использовать абстрактные типы (или дженерики) в Scala для возврата фактического класса?

Я не уверен, есть ли лучший способ выполнения этого:

trait Animal {
  val name: String
  val weight: Int

  type SubAnimal <: Animal

  def updateName(n: String) = returnMe(n, this.weight)
  def updateWeight(w: Int) = returnMe(this.name, w)
  // Abstract protected method
  protected def returnMe(n: String, w: Int): SubAnimal
}

case class Dog(name: String, weight: Int) extends Animal {
  type SubAnimal = Dog
  override def returnMe(n: String, w: Int): Dog = Dog("Dog: " + name, w)
}
case class Cat(name: String, weight: Int) extends Animal {
  type SubAnimal = Cat
  override def returnMe(n: String, w: Int): Cat = Cat("Cat: " + name, w)
}

val fido = Dog("Fido", 11)
println( fido )
val fido2 = fido.updateWeight(12)
println( fido2 )

Когда я запускаю код, я получаю следующий результат:

$ scala animal.scala 
Dog(Fido,11)
Dog(Dog: Fido,12)

Я хочу вернуть фактический тип рассматриваемого животного после updateName или updateWeight был вызван (т.е. не Животное ). Я знаю, что если я переопределю updateName и updateWeight напрямую, то будет возвращен правильный тип, и мне не нужно будет использовать абстрактный тип SubAnimal .

] Есть ли какой-нибудь хитрый способ избежать абстрактного типа для особого случая, когда значение абстрактного типа такое же, как у подкласса ?

(Это проблема "MyType").

9
задан olle kullberg 18 October 2010 в 21:56
поделиться