范型:
-
[B <: A] UpperBound 上界:B类型的上界是A类型,即B类型的父类是A类型
-
[B >: A] LowerBound 下界:B类型的下界是A类型,即B类型的子类是A类型
-
[B <% A] ViewBound 表示B类型要转换成A类型需要一个隐式转换函数
-
[B : A] ContextBound 表示B类型要转换成A类型需要一个隐式转换的值
[-A, +B]
-
[-A] 逆变,作为参数类型。如果A是T的子类,那么C[T]是C[A]的子类
-
[+B] 协变,作为返回类型。如果B是T的子类,那么C[B]是C[T]的子类
过程:
-
定义Girl类,构造函数给name和faceValue。
-
需要定义比较两个girl的规则,内部类OrderingGirl要继承Ordering特质,并重写compare方法。
-
这里ImplicitContext一般是定义在另外一个文件中,这里是为了方便。
-
这个过程类似于Java中继承Comparable接口,重写compare方法。
-
-
定义选择girl的方法choose,这里定义了Goddess类,其构造函数的参数用到了范型和范型的限制,在choose方法的实现中用到了柯里化和范型。
-
为了打印的结果明了,重写了Girl类的toString方法。
-
在main方法中新建Girl对象,新建Goddess对象,调用goddess的choose方法。
package test
/**
* @author: whua
* @create: 2018/10/08 16:29
* 比较两个Girl的faceValue
*/
object ImplicitContext {
//内部类,继承Ordering特质,类型为Girl
implicit object OrderingGirl extends Ordering[Girl] {
//重写比较的规则
override def compare(x: Girl, y: Girl): Int = if (x.faceValue > y.faceValue) 1 else -1
}
}
class Girl(val name: String, var faceValue: Int) {
override def toString: String = s"name: $name, faceValue: $faceValue"
}
class Goddess[T: Ordering](val v1: T, val v2: T) {
//比较两个girl的方法(柯里化,范型)
def choose()(implicit ord: Ordering[T]) = if (ord.gt(v1, v2)) v1 else v2
}
object Goddess {
def main(args: Array[String]): Unit = {
import ImplicitContext.OrderingGirl
val g1 = new Girl("yingying", 98)
val g2 = new Girl("zhuzhu", 90)
val goddess = new Goddess(g1, g2)
val ans = goddess.choose()
println(ans)
}
}