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