**
* [T <: Comparable[T]] 上界 upper bound java: <T extends Comparable>
* [T >: Comparable[T]] 下界 lower bound java: <T super Comparable>
* [T <% Comparable] 视图界定 view bound
* [T : Comparable] 上下文界定 context bound
* [-T] 逆变 方法输入参数
* [+T] 协变 方法返回
*
*/
class Pair[T <: Comparable[T]] {
def bigger(first: T, second: T): T = {
if(first.compareTo(second) > 0) first else second
}
}
object Pair {
def main(args: Array[String]): Unit = {
//val p = new Pair[String]
//val r = p.bigger("hadoop", "spark")
//val p1 = new Pair[Integer]
//将上界改成视图界定,Scala的Int也可以比较了(隐式转换)
val p1 = new Pair[Int]
//scala中的Int没有实现Comparable接口,所以没法执行
//java中的Integer有实现Comparable接口,可以比
val r = p1.bigger(10, 8)
println(r)
}
}
自定义类型实现比较
使用上界实现隐式转换:
class Girl(val name: String, var age: Int) extends Ordered[Girl]{
override def compare(that: Girl): Int = {
this.age - that.age
}
override def toString = s"Girl($name, $age)"
}
class MissRight[T <: Ordered[T]] {
def choose(first: T, second: T): T = {
if(first > second) first else second
}
}
object MissRight {
def main(args: Array[String]): Unit = {
val missRight = new MissRight[Girl]
val g1 = new Girl("aaa", 18)
val g2 = new Girl("bbb", 19)
val g = missRight.choose(g1, g2)
println(g)
}
}
使用视图界定实现隐式转换:
//视图界定:会有一个隐式转换将T转换成Ordered[T]
//视图界定需要一个隐式转换方法或隐式转换函数
class Pair2[T <% Ordered[T]] {
def select(first: T, second: T): T = {
if(first > second) first else second
}
}
object Pair2 {
def main(args: Array[String]): Unit = {
import MyContext.girlToOrderedGirl
val p = new Pair2[Girl2]
val g1 = new Girl2("ab", 88.98)
val g2 = new Girl2("hatna", 99.99)
val g = p.select(g1, g2)
println(g)
}
}
//不把比较规则写到这个类中,但是还是要具备比较的功能
class Girl2(val name: String, var fv: Double) {
override def toString = s"Girl2($name, $fv)"
}
import java.io.File
object MyContext {
implicit val aaa = 111
implicit val bbb = 111.111
//如果既有相同功能的隐式转换方法和函数,优先调用隐式转换函数
implicit def fileToRichFile(file: File): RichFile = {
println("method invoked")
new RichFile(file)
}
implicit val file2RichFIle = (file: File) => {
println("function invoked")
new RichFile(file)
}
implicit def girlToOrderedGirl(girl: Girl2): Ordered[Girl2] = new Ordered[Girl2] {
override def compare(that: Girl2): Int = {
//升序
(girl.fv - that.fv).toInt
}
}
implicit val g2OreredGirl = (girl: Girl2) => new Ordered[Girl2] {
override def compare(that: Girl2): Int = {
println("function invoked")
//降序
(that.fv - girl.fv).toInt
}
}
//隐式参数
implicit object OrderingBoy extends Ordering[Boy] {
override def compare(x: Boy, y: Boy): Int = {
(x.fv - y.fv).toInt
}
}
}
视图界定和上界界定就是来实现隐式转换的:
上下文界定:
class Boy(val name: String, var fv: Double) {
override def toString = s"Boy($name, $fv)"
}
//上下文界定,也是实现隐射转换的
//上下文界定需要一个隐式转换参数
class Pair3[T : Ordering] {
def choose(first: T, second: T): T = {
val ord: Ordering[T] = implicitly[Ordering[T]]
if(ord.gt(first, second)) first else second
}
}
object Pair3{
def main(args: Array[String]): Unit = {
import MyContext.OrderingBoy
val p = new Pair3[Boy]
val b1 = new Boy("laoduan", 99.99)
val b2 = new Boy("xiaozhao", 9999.99)
val b = p.choose(b1, b2)
println(b)
}
}
使用柯里化实现隐式转换:
//即不用视图界定,又不用上下文界定,但是要实现隐射转换
//结合柯里化实现
class Pair4[T] {
//使用柯里化方法接口隐式函数或隐式方法,可以实现类似视图界定的功能
def select(first: T, second: T)(implicit f: T => Ordered[T]): T = {
if (first > second) first else second
}
//使用柯里化方法接口隐式参数,可以实现类似上下文界定的功能
def choose(first: T, second: T)(implicit ord: Ordering[T]): T = {
if(ord.gt(first, second)) first else second
}
}
object Pair4 {
def main(args: Array[String]): Unit = {
val arr = Array[Int](1,2,3,9,8,7,5)
// Int 到 Ordering[Int] 的隐式转换参数
arr.sorted
//arr.sortBy()
val p = new Pair4[Boy]
import MyContext.OrderingBoy
// implicit val f = (g: Girl2) => new Ordered[Girl2]{
// override def compare(that: Girl2): Int = {
//
// println(“function invoked”)
// //降序
// (that.fv - g.fv).toInt
//
// }
// }
val g1 = new Boy(“ab”, 88.98)
val g2 = new Boy(“hatna”, 99.99)
//val g = p.select(g1, g2)
val g = p.choose(g1, g2)
println(g)
}
}
隐式转换总结:
什么是隐式转换:在Scala中,可以对方法进行增强或扩展方法的功能叫做隐射转换,本质就是装饰模式
有哪些语法可以实现隐式转换呢?
视图界定:需要隐式转换函数或隐式方法
上下文界定:需要隐式转换参数
柯里化,有两种方式,一种是传入隐式转换方法,另外一种隐式转换参数