乐趣区

关于scala:Scala-泛型

泛型

上面是相似于 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())
  }
}
退出移动版