集合的协方差
因为集合在元素类型*中通常是协变的,所以可以在期望超类型的地方传递子类型的集合:
trait Animal { def name: String }
case class Dog(name: String) extends Animal
object Animal {
def printAnimalNames(animals: Seq[Animal]) = {
animals.foreach(animal => println(animal.name))
}
}
val myDogs: Seq[Dog] = Seq(Dog("Curly"), Dog("Larry"), Dog("Moe"))
Animal.printAnimalNames(myDogs)
// Curly
// Larry
// Moe
它可能看起来不像魔术,但是 Seq[Dog]
被一个期望 Seq[Animal]
的方法接受的事实是一个更高级的类型(这里:Seq
)在其类型参数中是协变的整个概念。
*
一个反例是标准库的 Set