Scala 泛型的用法

泛型

就是一种不确定的数据类型,可以支持多种类型

定义泛型方法

在scala中,使用方括号来定义类型参数。

语法格式
def 方法名[泛型名称](..) = {
    //...
}
代码示例
object Test01 {
  /**
   * 没有泛型支持
   *
   * @param array 接收一个int 型的集合
   * @return 返回集合长度除以2 所对应索引的值
   */
  def getMiddle(array: Array[Int]): Int = array(array.length / 2)

  /**
   * 有泛型支持
   * @param array 接收一个集合
   * @tparam T 集合可以是任意类型
   * @return  返回集合长度除以2 所对应索引的值
   */
  def getMiddleElement[T](array: Array[T]): T = {
    array(array.length / 2)
  }

  def main(args: Array[String]): Unit = {
    //调用 getMiddle 方法
    println(Array(1,2,3,4,5))

    //调用getMiddleElement 方法
    println(getMiddleElement(Array(1,2,3,4,5)))
    println(getMiddleElement(Array("a","b","c","d","e")))
  }
}

定义泛型类

语法格式
  • 定义一个泛型类,直接在类名后面加上方括号,指定要使用的泛型参数
  • 指定类对应的泛型参数后,就使用这些类型参数来定义变量了
class[T](val 变量名: T)
代码示例
object Test02 {

  //定义一个 Pair泛型类
  //Pair类包含两个字段,而且两个字段的类型不固定
  case class Pair[T](var a: T, var b: T)

  def main(args: Array[String]): Unit = {
    //创建不同类型泛型类对象
    val pair1 = Pair("hadoop","Storm")
    val pair2 = Pair("hadoop",2018)
    val pair3 = Pair(1.2,3.0)
    val pair4 = Pair("hadoop",Some(1.9))
    //打印
    println(s"p = ${pair1}")
    println(s"p = ${pair2}")
    println(s"p = ${pair3}")
    println(s"p = ${pair4}")

  }
}

泛型上下界

我们在定义方法/类的泛型时,限定必须从哪个类继承、或者必须是哪个类的父类。此时,就需要使用到上下界。

上界定义

使用<: 类型名表示给类型添加一个上界,表示泛型参数必须要从该类(或本身)继承

语法格式
[T <: 类型]
上界代码示例
object Test03 {
  //定义一个Person类
  class Person
  //定义一个Student类,继承Person类
  class Student extends Person
  def demo[T <:Person](a:Array[T]): Unit = println(a)

  def main(args: Array[String]): Unit = {
    //编译成功 因为是 Person 的子类
    demo(Array(new Person))
    demo(Array(new Student))
    //编译出错, 必须是Person的子类
//    demo(Array("hadoop"))
  }
}
下界定义

上界是要求必须是某个类的子类,或者必须从某个类继承,而下界是必须是某个类的父类(或本身)
如果类既有上界、又有下界。下界写在前面,上界写在后面

语法格式
[T >: 类型]
下界代码示例
object Test04 {
  //定义一个Person类
  class Person
  //定义一个Policeman类,继承Person类
  class Policeman extends Person
  //定义一个Superman类,继承Policeman类
  class Superman extends Policeman

  /**
   * 定义一个demo泛型方法
   * 限定demo方法的Array元素类型只能是Person、Policeman
   * @param array 接收一个Array参数
   * @tparam T 泛型
   */
  def demo[T >: Policeman](array: Array[T]): Unit = println(array)

  def main(args: Array[String]): Unit = {
    //编译成功
    demo(Array(new Person))
    demo(Array(new Policeman))
    //运行时报编译 报错  Superman是Policeman的子类 不是父类
//    demo(Array(new Superman))
  }
}

泛型 协变、逆变、非变

非变

    1. 默认泛型类是非变的,类型B是A的子类型,
    1. Pair[A]和Pair[B]没有任何从属关系

协变

    1. 协变参数化类型的方向和类型的方向是一致的。
    1. 类型B是A的子类型,Pair[B]可以认为是Pair[A]的子类型

逆变

    1. 逆变参数化类型的方向和类型的方向是相反的
    1. 类型B是A的子类型,Pair[A]反过来可以认为是Pair[B]的子类型
语法格式
//非变
class Pair[T]
//协变
class Pair[+T]
//逆变
class Pair[-T]
代码示例
object Test05 {
  //定义一个Super类、以及一个Sub类继承自Super类
  class Super
  class Sub extends Super
  //非变
  class Temp1[T]
  //协变
  class Temp2[+T]
  //逆变
  class Temp3[-T]

  def main(args: Array[String]): Unit = {
    val a: Temp1[Sub] = new Temp1[Sub]

    //编译报错
    //非变
    //    val b:Temp1[Super] =a

    //协变
    val c: Temp2[Sub] = new Temp2[Sub]
    val d: Temp2[Super] = c

    //逆变
    val e: Temp3[Super] = new Temp3[Super]
    val f: Temp3[Sub] = e
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值