Scala 泛型

一 泛型类

  在类Message[E]上标注泛型为E,则E可以在整个类中使用

object ScalaDemo {

  def main(args: Array[String]): Unit = {
    val msg = new Message[String]("hello")
    println(msg.get)
  }

}

class Message[E](val msg: E) {

  def get: E = msg

}

  

二 泛型方法

  在方法midValue[E]上标注泛型为E,则类型E可以在方法体、参数和返回值上使用

object ScalaDemo {

  def main(args: Array[String]): Unit = {
    val msg = new Message
    val midValue: Int = msg.midValue((1 to 5).toList)
  }

}

class Message {

  def midValue[E](list: List[E]): E = {
    list(list.size / 2)
  }

}

 

三 泛型上界

  CommonCompare[T <: Comparable[T]]表示类的泛型为T,且T为Comparable的子类。这样做的好处一是限定泛型的范围,而是泛型T可以使用Comparable中定义的方法。

object ScalaDemo {

  def main(args: Array[String]): Unit = {
    val compare1 = new CommonCompare[java.lang.Integer](10, 20)
    println(compare1.greater)

    val compare2 = new CommonCompare[java.lang.Float](10.5f, 20.5f)
    println(compare2.greater)

  }

}

class CommonCompare[T <: Comparable[T]](obj1: T, obj2: T) {

  def greater = if (obj1.compareTo(obj2) > 0) obj1 else obj2

}

  

四 泛型下界

  与泛型上界的严格范围约束不同,在泛型下界中,如方法biophony[T>:Animal],如果是Animal类型相关的,父类按父类处理,自身及子类按Animal处理,其他不相关的按Object处理。在泛型上界中,泛型类是上界类的子类,一定可以调用上界类的方法。而在泛型下界中,泛型类是下界类的父类,不确定是否能调用下界子类中的方法,唯一确定的是泛型类为Object的子类。

object ScalaDemo {

  def main(args: Array[String]): Unit = {

    //父类
    val earths: Seq[Earth] = biophony(Seq(new Earth))
    earths.foreach(_.sound) // hello

    //自身
    val animals: Seq[Animal] = biophony(Seq(new Animal))
    animals.foreach(_.sound)  // animal sound

    //子类对象,父类引用
    val birds: Seq[Animal] = biophony(Seq(new Bird))
    birds.foreach(_.sound)  // bird sound

    //和Animal无关的按照Object处理
    val moons: Seq[Object] = biophony(Seq(new Moon))


  }

  //泛型下界为Animal
  def biophony[T>:Animal](things:Seq[T]) = things

}

class Earth{
  def sound=println("hello")
}

class Animal extends Earth{
  override def sound: Unit = println("animal sound")
}

class Bird extends Animal{
  override def sound: Unit = println("bird sound")
}

class Moon

  

五 视图界定

  在视图界定中,泛型类可以经过隐式转换以满足要求。CommonCompare[Person]后面的泛型可以随便写(泛型上界则不能这样),或者干脆省略,因为都会经过隐式转换。参数的实际类型或经过隐式转化的类型后是否满足泛型类型要求,才是本质。中括号里的泛型类型标注没有意义。

object ScalaDemo {

  implicit def orderedPerson(p:Person) = new Ordered[Person] {
    override def compare(that: Person): Int = p.age - that.age
  }

  def main(args: Array[String]): Unit = {
    val zs = new Person("zs", 13)
    val ls = new Person("ls", 14)
    //此时Person还不是Ordered的子类,但这样写不报错,因为编译器认为可能会有隐式转换,运行才报错
    val cc = new CommonCompare[Person](zs, ls)
    println(cc.older.name)

  }

}

class Person(val name: String, val age: Int)

class CommonCompare[T <% Ordered[T]](obj1: T, obj2: T) {
  // > 等同于 this.compare(that) > 0
  def older = if (obj1 > obj2) obj1 else obj2
}

  

 

原文地址:https://www.cnblogs.com/noyouth/p/12833202.html