【scala专栏_持续更新】28_scala泛型

【大纲】
在这里插入图片描述

【正文】

1.【结论】概念

泛型,即泛指某些种具体的数据类型,用[数据类型]表示

之前在数组和集合中使用过 如 Array[Int]

2.【结论】泛型方法

0.作用
    将泛型[T]定义在方法的声明上,让方法的参数使用此泛型[T]来作为参数的类型,则调用方法时,实际给的参数的数据类型是什么,方法中的[T]就是什么
    
# 注意:
    T可以是任意大写字母

示例

# 不使用泛型时:只能获取Int类型数组的中间元素

object T1 {
  def getMid(a:Array[Int]) = a(a.length / 2)
  
  def main(args: Array[String]): Unit = {
    val b = getMid(Array(1,2,3,4,5))
    println(b) // 效果:3
  }
}

# 使用泛型:可以获取任何类型数组的中间元素

object T1 {
  def getMid[T](a:Array[T]) = a(a.length / 2)

  def main(args: Array[String]): Unit = {
    val b = getMid(Array(1,2,3,4,5)) // val b = getMid[Int](Array(1,2,3,4,5))  [Int]可省略
    println(b) // 效果:3

    val c = getMid(Array('a','b','c')) // val c = getMid[Char](Array('a','b','c')) [Char]可省略
    println(c) // 效果:b
  }
}

3.【结论】泛型类

0.作用
    将泛型[T]定义在类的声明上,让类的成员参数使用此泛型[T]来作为数据类型,则创建对象时,实际给的成员的数据类型是什么,类中的[T]就是什么

示例

# 需求:
    0.定义一个Pair类,该类包含两个成员字段,且两个字段的类型不固定
    1.创建不同类型的Pair类对象,并打印

# 实现:
object TClass {
  class Pair[T](var a:T, var b:T)

  def main(args: Array[String]): Unit = {
    val p1 = new Pair(10, 20) // val p1 = new Pair[Int](10, 20) [Int]可省略
    println(p1.a, p1.b) // 效果:(10,20)

    val p2 = new Pair("a", "b") // val p2 = new Pair[String]("a", "b") [String]可省略
    println(p2.a, p2.b) // 效果:(a,b)
  }
}

4.【结论】泛型特质

0.作用
    将泛型定义在特质的声明上,让特质的成员使用此泛型作为数据类型,则在子类继承特质时,指定特质的数据类型,即可传递给特质的泛型

示例

object TTrait {
  trait Person[T]{
    val name:T
    def run(sex:T) = println(sex)
  }
  object Children extends Person[String]{ // 声明了特质的实际泛型是[String]
    override val name: String = "小学生"
  }
  def main(args: Array[String]): Unit = {
    val name = Children.name
    println(name) // 效果:小学生
    
    Children.run("跑不掉") // 效果:跑不掉
  }
}

5.【结论】泛型的上界

[T <: 泛型的上界数据类型],代表泛型T的数据类型,必须是上界数据类型或其子

示例

object TUp {
  class Person

  class Student extends Person
  // 定义泛型方法 指定泛型的上届
  def demo[T <: Person](arr:Array[T]) = println(arr)

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

    val b = demo(Array(1,2)) // 编译会报错 因为只能传入Person或者它的子类型
  }
}

6.【结论】泛型的下界

0.下界:
    [T >: 泛型的下界数据类型],代表泛型T的数据类型,必须是下界数据类型或其父

1.上下界:
    [T >: 泛型的下界数据类型 <: 泛型的上界数据类型]

示例

# 泛型的下界

object TDown {
  class Person

  class Policeman extends Person

  class Superman extends Policeman

  def demo[T >:Policeman](arr:Array[T]) = println(arr)

  def main(args: Array[String]): Unit = {
    demo(Array(new Policeman)) // 效果:[Lcom.wsy.TDown$Policeman;@23223dd8
    demo(Array(new Person)) // 效果:[Lcom.wsy.TDown$Person;@4ec6a292
    demo(Array(new Superman)) // 会报错 泛型规定了只能是Policeman及其父
  }
}
# 泛型的上下界

object TDown {
  class Person

  class Policeman extends Person

  class Superman extends Policeman

  def demo[T >:Policeman <:Policeman](arr:Array[T]) = println(arr)

  def main(args: Array[String]): Unit = {
    demo(Array(new Policeman)) // 效果:[Lcom.wsy.TDown$Policeman;@23223dd8
//    demo(Array(new Person)) // 会报错 泛型规定了只能是Policeman
    demo(Array(new Superman)) // 会报错 泛型规定了只能是Policeman
  }
}

7.【结论】泛型类的非变

0.作用
    类A是类B的父,但Pair[A]和Pair[B]之间没有任何关系
    
1.语法
    class Pair[T]{}
    
    # 注意:泛型类默认就是非变

示例

object Tf {
  class Super
  class Sub extends Super
  class Temp1[T]
  def main(args: Array[String]): Unit = {
    val t1:Temp1[Sub] = new Temp1[Sub]()

//    val t2:Temp1[Super] = new Temp1[Sub] // 效果:会报错 Temp1[Super]和Temp1[Sub]没有任何子父关系

//    val t3:Temp1[Sub] = new Temp1[Super] // 效果:会报错 Temp1[Sub]和Temp1[Super]没有任何子父关系
  }
}

8.【结论】泛型类的协变

0.作用
    类A是类B的父,Pair[A]也是Pair[B]的父

1.语法
    class Pair[+T]{}

示例

object Tx {
  class Super
  class Sub extends Super
  class Temp1[+T]
  def main(args: Array[String]): Unit = {
    val t1:Temp1[Sub] = new Temp1[Sub]()
    val t2:Temp1[Super] = new Temp1[Sub]
//    val t3:Temp1[Sub] = new Temp1[Super] // 效果:会报错 因为Temp1[Sub]是Temp1[Super]的子
  }
}

9.【结论】泛型类的逆变

0.作用:
    类A是类B的父,Pair[A]是Pair[B]的子
    
1.语法:
    1.语法
    class Pair[-T]{}

示例

object Tn {
  class Super
  class Sub extends Super
  class Temp1[-T]
  def main(args: Array[String]): Unit = {
    val t1:Temp1[Sub] = new Temp1[Sub]()
//    val t2:Temp1[Super] = new Temp1[Sub] // 效果:会报错 因为Temp1[Super]是Temp1[Sub]的子
    val t3:Temp1[Sub] = new Temp1[Super]
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cheese海盐芝士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值