泛型

上面是相似于java的泛型,有三个类Shape(形态)、Rectangle(长方形)、Square(正方形)。Shape是Rectangle的父类,Rectangle是Square的父类。所以咱们定义变量的时候,能够申明他为Shape类型,在new的时候给具体的类型。
Draw1这里有个泛型T,咱们能够看到定义变量的时候,这里的类型是不能有父子类关系的。

object GenericDemo {  def main(args: Array[String]): Unit = {    val shape1: Shape = new Shape()    var shape2: Shape = new Rectangle()    var shape3: Shape = new Square()    val draw1: Draw1[Shape] = new Draw1[Shape]()    // val draw2: Draw1[Shape] = new Draw1[Rectangle]() // error    // val draw3: Draw1[Shape] = new Draw1[Square]() // error  }}class Shape {}class Rectangle extends Shape {}class Square extends Rectangle {}class Draw1[T]() {}

协变和逆变

下面不能编译是因为Draw1[Shape]和new Draw1[Rectangle]并没有父子关系,Scala通过协变能够让他们有父子关系:
在泛型T后面加一个+

class Draw2[+T]() {}

而后在main函数中就能够调用了:

val draw2: Draw2[Shape] = new Draw2[Rectangle]()val draw3: Draw2[Shape] = new Draw2[Square]()

scala中还有逆变,就是颠倒Draw3[T]的父子关系:
在泛型T后面加一个-

class Draw3[-T]() {}

而后在main函数中就能够调用了:

val draw4: Draw3[Rectangle] = new Draw3[Shape]()val draw5: Draw3[Square] = new Draw3[Shape]()

上界下界

上界下界就是定义泛型的边界。
比方Draw2通过<:Shape2来定义泛型的上界,那Draw2的参数就是Shape2类以及子类。printInfo办法是Shape2的办法,所以printInfo中能够间接调用。t.printInfo()办法,
Draw3通过>:Rectangle2来定义泛型的下界,那Draw3的参数就是Rectangle2类以及父类,此时他只有Any的办法。

object GenericDemo2 {  def main(args: Array[String]): Unit = {    val draw1: Draw2[Shape2] = new Draw2(new Shape2())    val draw2: Draw2[Shape2] = new Draw2(new Rectangle2())    val draw3: Draw2[Shape2] = new Draw2(new Square2())    draw1.printInfo() // 形态    draw2.printInfo() // 长方形    draw3.printInfo() // 正方形    println("-------------")    val draw4: Draw3[Shape2] = new Draw3(new Shape2())    val draw5: Draw3[Rectangle2] = new Draw3(new Rectangle2())    //val draw6: Draw3[Square2] = new Draw3(new Square2()) // error    draw4.printInfo() // class com.scala.learn12.Shape2    draw5.printInfo() // class com.scala.learn12.Rectangle2    // draw3.printInfo()  }}class Shape2 {  def printInfo(): Unit = {    println("形态")  }}class Rectangle2 extends Shape2 {  @Override  override def printInfo(): Unit = {    println("长方形")  }}class Square2 extends Rectangle2 {  @Override  override def printInfo(): Unit = {    println("正方形")  }}class Draw2[T <: Shape2](t: T) {  def printInfo(): Unit = {    t.printInfo()  }}class Draw3[T >: Rectangle2](t: T) {  def printInfo(): Unit = {    println(t.getClass())  }}