问题
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.
回答1:
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!
来源:https://stackoverflow.com/questions/10199254/overriding-subclass-methods-with-subclassed-arguments