Overriding subclass methods with subclassed arguments?
inheritance, overriding, scala
Solution
abstract class Animal[T <: Animal[T]] {
def mateWith(that: T)
}
class Cow extends Animal[Cow] {
override def mateWith(that: Cow) { println("cow") }
}
class Dog extends Animal[Dog] {
override def mateWith(that: Dog) { println("dog") }
}
And use it like this:
scala> (new Cow).mateWith(new Cow)
cow
scala> (new Cow).mateWith(new Dog)
<console>:17: error: type mismatch;
found : Dog
required: Cow
(new Cow).mateWith(new Dog)
^
No exception-throwing code needed; the type system handles it for you at compile-time!
Problem
How can I force base methods to take in the same specific subclass instance when overriden by a subclass? i.e.: ``` abstract class Animal { def mateWith(that: Animal) } class Cow extends Animal { override def mateWith...? } ``` Logically, a `Cow` should only be able to `mateWith` another `Cow`. However, if I do `override def mateWith(that: Cow)`, this doesn't actually override the base class method (which I want it to, since I want to enforce its existence in the subclass). I could check to make sure the other instance is of type Cow, and throw an exception if it isn't - is this my best option? What if I have more animals? I would have to repeat the exception-throwing code.