Big data, a good programmer, shares the generics of the Scala series.
Big data, a good programmer, shares the generics of the Scala series. Classes with one or more type parameters are generic.
Definition of generic classes:
/ / Class definition with type parameter A
Class Stack [A] {
Private var elements: List [A] = Nil
/ / generic method
Def push (x: a) {elements = x:: elements}
Def peek: a = elements.head
Def pop (): a = {
Val currentTop = peek
Elements = elements.tail
CurrentTop
}
}
For the use of generic classes, the type parameter An is replaced by a specific type.
Val stack = new Stack [Int]
Stack.push (1)
Stack.push (2)
Println (stack.pop) / / prints 2
Println (stack.pop) / / prints 1
1. Covariation
Define a type List [+ A], if An is covariant, meaning: for type An and BMagee An are subtypes of B, then list [A] is a subtype of List [B].
Abstract class Animal {
Def name: String
}
Case class Cat (name: String) extends Animal
Case class Dog (name: String) extends Animal
The Scala standard library has a generic class sealed abstract class List [+ A], because the type parameters in it are covariant, so the following program is called successfully.
Object CovarianceTest extends App {
/ / define parameter type list [Animal]
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"))
/ / input parameter type is List [Cat]
PrintAnimalNames (cats)
/ / Whiskers
/ / Tom
/ / input parameter type is List [Dog]
PrintAnimalNames (dogs)
/ / Fido
/ / Rex
}
two。 Inverse transformation
Define a type Writer [- A], if An is inverted, meaning: for type An and BMagee An is a subtype of B, then Writer [B] is a subtype of Writer [A].
Abstract class Animal {
Def name: String
}
Case class Cat (name: String) extends Animal
Case class Dog (name: String) extends Animal
Define the print information class that operates corresponding to the above class
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)
}
Inversion test
Object ContravarianceTest extends App {
Val myCat: Cat = Cat ("Boots")
/ / define the parameter type as Printer [Cat]
Def printMyCat (printer: Printer [Cat]): Unit = {
Printer.print (myCat)
}
Val catPrinter: Printer [Cat] = new CatPrinter
Val animalPrinter: Printer [Animal] = new AnimalPrinter
PrintMyCat (catPrinter)
/ / you can pass the parameter type as Printer [Animal]
PrintMyCat (animalPrinter)
}
3. Upper bound
Upper bound definition: t: B] (elem: U): Node [U]
}
Case class ListNode [+ B] (h: B, t: Node [B]) extends Node [B] {
Def prepend [U >: B] (elem: U): ListNode [U] = ListNode (elem, this)
Def head: B = h
Def tail: Node [B] = t
}
Case class Nil [+ B] () extends Node [B] {
Def prepend [U >: B] (elem: U): ListNode [U] = ListNode (elem, this)
}
test
Trait Bird
Case class AfricanSwallow () extends Bird
Case class EuropeanSwallow () extends Bird
Val africanSwallowList= ListNode [AfricanSwallow] (AfricanSwallow (), Nil ())
Val birdList: Node [Bird] = africanSwallowList
BirdList.prepend (new EuropeanSwallow)
5 event horizon (view bounds)
Note: it is out of date, just understand it.
Horizon definition: a