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]() {}
【Scala - 泛型】然后在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())
}
}
推荐阅读
- ts泛型使用举例
- Kotlin泛型的高级特性(六)
- Scala判断字符串是否相等
- Scala|Scala 从Array数组的构造过程理解apply()
- scala基础(一)
- Scala学习笔记|Scala学习笔记 A2/L1篇 - 注解 Annotations
- Kotlin|Kotlin 泛型之类型擦除
- Ubuntu16.04/Scala2.11.8安装教程
- scala|scala DateTime 库
- Android 泛型与ArrayAdapter适配器 初步入门