2012-04-17 54 views
6

如何强制base方法在被子类重写时接受相同的特定子类实例?用子类参数重写子类方法?

即:

abstract class Animal { 
    def mateWith(that: Animal) 
} 

class Cow extends Animal { 
    override def mateWith...? 
} 

从逻辑上讲,应该Cow只能够mateWith另一个Cow。但是,如果我做override def mateWith(that: Cow),这实际上并没有覆盖基类方法(我希望它,因为我想强制它的存在在子类中)。

我可以检查以确保其他实例的类型为Cow,如果不是,则抛出异常 - 这是我的最佳选择吗?如果我有更多的动物呢?我将不得不重复抛出异常的代码。

回答

11
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") } 
} 

而且使用这样的:

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) 
           ^

不需要异常抛出代码;类型系统会在编译时为您处理它!

+1

甜美的交易,斯卡拉的方便! – 2012-04-17 21:27:53

+1

我不太确定“方便”,但表现力很强。 – 2013-02-07 04:32:42

+1

以为我会重温这个 - 这被称为[f-bound-polymorphism](https://twitter.github.io/scala_school/advanced-types.html#fbounded)。 – 2015-10-14 21:10:22