I am not sure if there is a better way of doing this:
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 )
When I run the code I get this output:
$ scala animal.scala
Dog(Fido,11)
Dog(Dog: Fido,12)
I want to return the actual type of the animal in question after the updateName
or updateWeight
has been called (i.e. not Animal
). I know that if I override updateName
and updateWeight
directly, then the correct type will be returned and I do not have to use the abstract type SubAnimal
.
Is there some tricky way of escaping the abstract type for the special case where the value of the abstract type is the same as the subclass?
(This is know as the "MyType" problem).