类型关系
Scala 支持在泛型类上使用型变注释,用来表示复杂类型、组合类型的子类型关系间的相关性
协变 T
,变化方向相同,通常用在生产
假设
A extends T
, 对于Clazz[ T]
,则Clazz[A]
也可看做Clazz[T]
// 官网示例
abstract class Animal {
def name: String
}
case class Cat(name: String) extends Animal
case class Dog(name: String) extends Animal
由于 Scala 标准库中不可变 List
的定义为 List[ A]
,因此 List[Cat]
是 List[Animal]
的子类型, List[Dog]
也是 List[Animal]
的子类型,所以可直接将他们当作 List[Animal]
使用。
// 官网示例
object CovarianceTest extends App {
def printAnimalNames(animals: List[Animal]): Unit = {
animals.foreach { animal =>
println(animal.name)
}
}
val cats: List[Cat] = List(Cat("Whiskers"), Cat("Tom"))
val dogs: List[Dog] = List(Dog("Fido"), Dog("Rex"))
printAnimalNames(cats)
// Whiskers
// Tom
printAnimalNames(dogs)
// Fido
// Rex
}
逆变 -T
,变化方向相反,通常用在消费
假设
A extends T
, 对于Clazz[-T]
,则Clazz[T]
也可看做Clazz[A]
// 官网示例
abstract class Printer[-A] {
def print(value: A): Unit
}
class AnimalPrinter extends Printer[Animal] {
def print(animal: Animal): Unit =
println("The animal's name is: " animal.name)
}
class CatPrinter extends Printer[Cat] {
def print(cat: Cat): Unit =
println("The cat's name is: " cat.name)
}
object ContravarianceTest extends App {
val myCat: Cat = Cat("Boots")
def printMyCat(printer: Printer[Cat]): Unit = {
printer.print(myCat)
}
val catPrinter: Printer[Cat] = new CatPrinter
val animalPrinter: Printer[Animal] = new AnimalPrinter
printMyCat(catPrinter)
printMyCat(animalPrinter) // 将 Printer[Animal] 当作 Printer[Cat] 使用
}