scala 泛型

泛型类:
 * 在类声明时,定义一些泛型类型,然后在类的内部,就可以使用这些泛型类型
 * 在需要对类中的某些成员,如字段或方法中的参数进行统一的类型限制时,可以使用泛型类,使得程序具有更好的健壮性和稳定性
 * 在使用类的时候,将类型参数替换为实际的类型即可。
 * scala会自动推断泛型类型:给泛型类型的字段赋值时,scala会自动对类型进行推断

class F01[T1, T2, T3](val name: T1) {
  var age: T2 = _
  var sex: T3 = _
  def say() = {
    println(name)
  }
}

object F01 {
  def main(args: Array[String]): Unit = {
    val p = new F01[String, Int, String]("张三")
    p.age = 12
    p.sex = "男"
    p.say()
  }
}

泛型函数:
 * 与泛型类相似,在声明函数时指定泛型类型,然后在函数体内,多个变量或返回值,就可以使用泛型类型进行声明。
 * 可以通过给使用了泛型类型的变量传递值,让scala自动推断泛型的实际类型,也可以在调用函数的时候,手动指定泛型的实际类型

class F02 {
  def say[T1,T2,T3]( name:T1, age:T2):T3 = {
    (name + "-" + age).asInstanceOf[T3]
  }
}
object F02{
  def main(args: Array[String]): Unit = {
    val p = new F02
    println(p.say("张三", 12))//scala会自动推断泛型的实际类型
    println(p.say[String,Int,String]("李四", 14))//等同于上面
  }
}

泛型类的上边界

<: 上边界定义的符号,[T <: C1],即泛型T只能是C1及其子类

class C1
class C1_1 extends C1
class C1_2 extends C1

class C2
class C2_1 extends C2
class C2_2 extends C2

//<: 上边界,即泛型T只能是C1及其子类
class F03[T <: C1] {
  def say(p: T) = {
    println(p.getClass)
  }
}

object F03 {
  def main(args: Array[String]): Unit = {
    val c1 = new F03[C1]
    val c1_1 = new C1_1
    val c1_2 = new C1_2

    c1.say(c1_1) //class fanxin.C1_1
    c1.say(c1_2) //class fanxin.C1_2

    val c1_3 = new F03[C1_1]
    c1_3.say(c1_1) //class fanxin.C1_1
    //以下代码错误,C1_2 不是 C1_1 的子类
    //    c1_3.say(c1_2)

    //以下代码错误,C2 不是 C1的子类
    //    val c2 = new F03[C2]
  }
}

泛型类的下边界

>:  下边界,T>: Adult,即泛型T只能取Adult类及其父类

class People
class Adult extends People
class Children extends Adult

//>:  下边界,即泛型T只能取Adult类及其父类
class F04[T >: Adult] {
  def say(p: T) = {
    println(p.getClass())
  }
}

object F04 {
  def main(args: Array[String]): Unit = {
    val p = new F04[People]
    p.say(new People)

    val a = new F04[Adult]
    p.say(new Adult)
    //以下代码错误,Children是Adult的子类,超出下边界
    //    val c = new F04[Children]
  }
}

协变与逆变

 *协变,完美解决java中泛型的一些缺陷。
 * 如Professor 是 Master 的子类,那么Card[Professor] 是不是Card[Master]的子类呢?    
 * 在java中不是,因此带来局限性。而scala的协变可以解决这一问题。其实就是泛型的上边界的加强版
 * 与协变对应的是逆变,是泛型的下边界的加强版

class Master
class Professor extends Master
class Teacher extends Professor
class Student

//+T 协变,Professor 是 Master 的子类,那么Card[Professor] 就是 Card[Master] 的子类
class Card[+T]
//-T 逆变,规定了传入类型的下边界
class Card2[-T]

class F06 {
  def enter(car: Card[Master]) = {
    println("只有Master及其子类可以通过")
  }
  def enter2(car: Card2[Professor]) = {
    println("只有Professor及其父类可以通过")
  }
}

object F06 {
  def main(args: Array[String]): Unit = {
    val f = new F06
    f.enter(new Card[Master])
    f.enter(new Card[Professor])
    //下行代码错误,Card[Student] 不是 Card[Master]的子类
    //    f.enter(new Card[Student])

    f.enter2(new Card2[Professor])
    f.enter2(new Card2[Master])
    //下行代码错误,Card[Teacher] 不是 Card[Professor]的父类
    //    f.enter2(new Card2[Teacher])
  }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值