类型关系
Scala 支持在泛型类上使用型变注释,用来表示复杂类型、组合类型的子类型关系间的相关性
协变 +T,变化方向相同,通常用在生产
+T
假设 A extends T, 对于 Clazz[+T],则 Clazz[A] 也可看做 Clazz[T]
A extends T
Clazz[+T]
Clazz[A]
Clazz[T]
// 官网示例abstract class Animal { def name: String}case class Cat(name: String) extends Animalcase class Dog(name: String) extends Animal
// 官网示例
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] 使用。
List
List[+A]
List[Cat]
List[Animal]
List[Dog]
// 官网示例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}
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,变化方向相反,通常用在消费
-T
假设 A extends T, 对于 Clazz[-T],则 Clazz[T] 也可看做 Clazz[A]
Clazz[-T]
// 官网示例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] 使用}
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] 使用
原文链接:http://www.cnblogs.com/yuanzam/p/11645056.html
本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728