设为首页 加入收藏

TOP

Scala泛型(一)
2023-07-23 13:24:48 】 浏览:323
Tags:Scala 泛型

泛型的定义

object _11_泛型 {
  def main(args: Array[String]): Unit = {
    //[A]  这个代表的就是泛型  ==》 在创建对象的时候,可以指定需要传进去的类型
    //作用就是在创建对象的时候,可以对传进去的参数一个约束,当设置泛型位int之后,那么传进去的值就必须是int
    //apply[A](xs: A*): List[A] = xs.toList
    val ints: List[Int] = List[Int](1, 2, 3, 4)

    //自己写一个?  单纯演示泛型语法的定义,没有什么实际的意义
    /**
     * 将泛型定义在类上,那么在整个类中,都可以使用该泛型,作用域是整个类
     * @tparam T
     */
    class TestFanXin[T](){
      def max(a:T,b:T)= a
    }
    //如果设置泛型位Int类型,那么方法的参数就只能传Int类型
    new TestFanXin[Int]().max(1,2)
    //如果设置泛型位String类型,那么方法的参数就只能传String类型
    new TestFanXin[String]().max("aa","bb")

    /**
     * 泛型也可以定义在方法上,如果定义在方法上,那么该泛型的作用域只能作用在该方法中
     * 出了该方法便不能生效
     */
    class TestFanXin1(){
      def max[T](a:T,b:T)= a
      def min[A](a:A,b:A)= b
    }
  }
}

泛型上下限

泛型的上下限的作用是对传入的泛型进行限定。
语法:

//泛型上限  只能够传Person 这个类和他的的子类
Class PersonList[T <: Person]{ 
}
//泛型下限 只能够传Person 这个类和他的的父类
Class PersonList[T >: Person]{ 
}

代码示例:

package com.doit.day02


object _12_泛型的上下限 {
  def main(args: Array[String]): Unit = {

    def sayHi[A <: Father](a:A): Unit ={
      println("test")
    }

    def sayHello[A >: Father](a:A): Unit ={
      println("test")
    }

    //调用sayHi的时候,传进去的参数因为有泛型的上界约定,所以只能传入Father和Father的子类
    sayHi(new Son())
    sayHi(new Father())
    //这边编译的时候虽然不报错,但是运行的时候会报错
//    sayHi(new GrandFather())

    //如果泛型是定义在方法上的,如果没有加泛型,是限制不住的,但是加了泛型,还是可以限制住的
//    sayHello[ABC](new ABC)
//    sayHello[Son](new Son)
    sayHello(new Father)
    sayHello(new GrandFather)


    class Test[A >:Father]{
      def sayHi(a:A) ={
        println("hello")
      }
    }

    new Test[Father].sayHi(new Father)
    //如果定义在类上的话,就能约束住了
//    new Test[Son].sayHi(new Son)
    new Test[GrandFather].sayHi(new GrandFather)




  }
}

class Son extends Father

class Father extends GrandFather

class GrandFather

class ABC

视图限定

约束本质:存在一个隐式转换,能够将T类型转换成B类型
泛型视图限定:T <% B

package com.doit.day02

object _13_视图限定 {
  def main(args: Array[String]): Unit = {

    class Bird(val name:String){
      def fly()={println(name + "飞走了")}
    }

    class ToyBird

    def bitBird[T <% Bird](b:T)=b.fly()

    bitBird[Bird](new Bird("小鸟"))

    implicit def toy2Bird(toyBird: ToyBird)= new Bird("玩具鸟")

    bitBird[ToyBird](new ToyBird)
  }
}

上下文限定

上下文限定是将泛型和隐式转换的结合产物,以下两者功能相同,使用上下文限定[A : Ordering]之后,方法内无法使用隐式参数名调用隐式参数,需要通过 implicitly[Ordering[A]]获取隐式变量,如果此时无法查找到对应类型的隐式变量,会发生出错误。

implicit val x = 1
val y = implicitly[Int]
val z = implicitly[Double]

语法:

def f[A : B](a: A) = println(a) 
//等同于 def f[A](a:A)(implicit arg:B[A])=println(a)```
代码示例:
```Scala
package com.doit.day02

object _14_上下文界定 {
  def main(args: Array[String]): Unit = {

    /**
     * 泛型的上下文界定
     */

    case class Tiger(age:Int,weight:Int)
    case class Cat(age:Int,weight:Int)
    //我想比较两个老虎的大小  单纯的老虎,没有实现compare方法的话,是没有办法调用compare来比较的
    //两个办法,第一个办法,在类上实现Ordered 特质,重写 compareTo方法
    //第二个方法,传一个比较器进去,这样他们就可以用比较器来比较了
    def bigger(tiger: Tiger,tiger1:Tiger,cmp:Ordering[Tiger]):Tiger={
      if (cmp.compare(tiger,tiger1)> 0) tiger else tiger1
    }

    //上面这种方法确实是可以比较,但是只能比较老虎,我想比较个猫好像就比较不了了
    //想比较猫,得重新在写一个
    def bigger1(cat: Cat,cat1:Cat,cmp:Ordering[Cat]):Cat={
      if (cmp.compare(cat,cat1)> 0) cat else cat1
    }

    //不过回头想比较狗狗,又要写一个,比较麻烦,不通用
    //这时候就可以定义泛型了
    def bigger2[T](t: T,t1:T,cmp:Ordering[T]):T={
      if (cmp.compare(t,t1)> 0) t else t1
    }

    //方法的调用  这样是没什么问题的
    //但是在马大爷眼里,这么写代码,多low啊,不符合马大爷的气质,他就开始搞事情了
    bigger2[Cat]
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Scala练习 下一篇scala异常和IO

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目