一 泛型类
在类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 }