scala快速入门系列【泛型】

2021-01-26 16:00:48 浏览数 (1)

本篇作为scala快速入门系列的第三十五篇博客,为大家带来的是关于泛型的内容。

泛型

scala和Java一样,类和特质、方法都可以支持泛型。我们在学习集合的时候,一般都会涉及到泛型。

那如何自己定义泛型呢?

定义一个泛型方法

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

语法

示例

  • 用一个方法来获取任意类型数组的中间的元素 – 不考虑泛型直接实现(基于Array[Int]实现) – 加入泛型支持

参考代码

不考虑泛型的实现

加入泛型支持


泛型类

scala的类也可以定义泛型。接下来,我们来学习如何定义scala的泛型类。

语法

  • 定义一个泛型类,直接在类名后面加上方括号,指定要使用的泛型参数
  • 指定类对应的泛型参数后,就使用这些类型参数来定义变量了

示例

  • 实现一个Pair泛型类
  • Pair类包含两个字段,而且两个字段的类型不固定
  • 创建不同类型泛型类对象,并打印

上下界

需求:

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

上界

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

语法

示例

  • 定义一个Person类
  • 定义一个Student类,继承Person类
  • 定义一个demo泛型方法,该方法接收一个Array参数
  • 定义一个demo泛型方法,该方法接收一个Array参数
  • 测试调用demo,传入不同元素类型的Array

参数代码

下界

上界是要求必须是某个类的子类,或者必须从某个类继承,而下界是必须是某个类的父类(或本身)

语法

[NOTE]

  • 如果类既有上界、又有下界。下界写在前面,上界写在后面

示例

  • 定义一个Person类
  • 定义一个Policeman类,继承Person类
  • 定义一个Superman类,继承Policeman类
  • 定义一个demo泛型方法,该方法接收一个Array参数
  • 限定demo方法的Array元素类型只能是Person、Policeman
  • 测试调用demo,传入不同元素类型的Array

参考代码1

参考代码2

代码语言:javascript复制
object _04GenericType {

  // 1. 定义类和子类
  class Person
  class Policeman extends Person
  class Superman extends Policeman


  // 2. 定义泛型方法,指定泛型的类型上下界
  def demo[T >: Policeman <: Person](array: Array[T])={
    println(array)
  }

  // 3. 调用demo方法,传入不同类型的数据进行测试
  def main(args: Array[String]): Unit = {
    demo(Array(new Person))
    demo(Array(new Policeman))
     
    // 编译报错:String类型并不是Person类型或者是它的子类
    // demo(Array(new Superman))

  }
}

协变、逆变、非变

spark的源代码中大量使用到了协变、逆变、非变,学习该知识点对我们将来阅读spark源代码很有帮助。

来看一个类型转换的问题:

如何让带有泛型的类支持类型转换呢?


非变

语法

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

协变

语法

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

逆变

语法

  • 类型B是A的子类型,Pair[A]反过来可以认为是Pair[B]的子类型
  • 参数化类型的方向和类型的方向是相反的

示例

  • 定义一个Super类、以及一个Sub类继承自Super类
  • 使用协变逆变非变分别定义三个泛型类
  • 分别创建泛型类来演示协变、逆变、非变

参考代码


本期的内容分享就到这里了,喜欢的小伙伴们记得点个赞,持续关注哟~下期为大家介绍的是scala的高阶函数,敬请期待٩(๑>◡<๑)۶

0 人点赞