开发者学堂课程【Scala 核心编程 - 进阶:Scala 上界介绍和应用实例1】学习笔记,与课程紧密连接,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/610/detail/9152
Scala 上界介绍和应用实例1
内容介绍
一、上界(Upper Bounds)介绍和使用
二、scala 中上界应用案例-要求
一、上界(Upper Bounds)介绍和使用
>java 中上界
在 Java 泛型里表示某个类型是A类型的子类型,使用 extends 关键字,这种形式叫 upper bounds(上限或上界),
语法如下:
<Textends A>
//或用通配符的形式:
<? extends A>
在Scala里面做了一个改进的形式:
>scala中上界
在scala 里表示某个类型是A类型的子类型,也称上界或上限,使用<:关键字,
语法如下:
[T <: A]
//或用通配符:
[_<: A]
二、scala中上界应用案例-要求
1)编写干个通用的类,可以进行 Int 之间、Float 之间、等实现了
Comparable 接口的值直接的比较.//java.lang.Integer
2)分别使用传统方法和上界的方式来完成,体会上界使用的好处
//如果用传统的方法来做,有几种类型就得写几种。如果用上界这个方式就可以做成通用的形式。
class CompareInt(n1:Int,n2:Int)
{
def greater =if
(
n1 >n2
)
n1 elsen2
}
class CompareCommT<:Comparable[U]](obj1:Tobj2: T){
def greater=if(obj1.compareTo(obj2)>0)obj1elseobj2
}
//映射转换Predef.scala
首先建个包:
建立文档:
可以看到:
package com.atguigu.chapter18.upperbounds
object UpperBoundsDemo01 {
def main(args: Array[String]): Unit = {
java.lang.Integer
}
}
这里的Integer做了什么角色:
事实上是实现了 comparable 这个接口,再往里看
这样就可以进行比较。
下面演示代码:
package com.atguigu.chapter18.upperbounds
object UpperBoundsDemo01 {
def main(args: Array[String]): Unit = {
val compareInt=newCompareInt(10
,
40) println(compareInt.greater)// 40
}
}
/*
编写一个通用的类,可以进行Int之间、Float之间、等实现了Comparable接口的值直接的比较.//java.lang.Integer
分别使用传统方法和上界的方式来完成,体会上界使用的好处。
*/
//传统方法
class CompareInt(n1: Int,n2: Int) {
//返回较大的值
def greater = if(n1 > n2) n1 else n2
}
点击运行:
正确。
但是传统的方法有个问题:
float还需要再写一份。
因为没用泛型,也没用到上下界。float是传不进去的。比如把10换成10.1,这个代码就不匹配了。当然也可以用其他方法,但是现在我们要用上界来解决。
下面讲解如何使用上界的方法来解决问题:
}
}
//使用上界(上限)来完成
//说明
//1.「T<:Comparable[T]]表示T类型是Comparable子类型
//2.即你传入的T类要继承Comparable接口
/
/3,这样就可以使用compareTo方法
/
/
4.这样的写法(使用上界的写法) 通用性比传统的好
class CommonCompare
【
T<:Comparable[T
]
】(obi1:T.obj2:T){
def greater = if (obj1.compareTo(obj2) > 0) obj1 else obj2}
下面实施一下:
package com.atguigu.chapter18.upperbounds
object UpperBoundsDemo01 {
def main(args: Array[String]): Unit = {
val compareInt=newCompareInt(10
,
40) println(compareInt.greater)// 40
//我们看一下这种方法能不能成功:val commonCompare1 = new CommonCompare(10, 40) println(commonCompare1.greater)
这样是否可以呢?填10和40有没有实现compare接口?10和40是Int类型,在Scala里并没有实现 compare。
所以会报错:
因为要求是实现 compare,我们知道integer它是实现了的。下面写代码:
//第一个用法
val commonCompare1 = new CommonCompare(Integer.valueof(10),Integer.valueof(40))//lnteger实现compare接口,因此就满足上界的子类型
//Int
println(commonCompare1.greater)
执行:
可以看出这个写法是可以实施的。
第二种方法:
val commonCompare2 = new CommonCompare(Float.valueOf(10.1),Float.valueof(42.1))//Int println(commonCompare1.greater)
}
//这样写大家看是否可以?答案是不可以的,他报错了,因为这里的float是scala里面的float,点进去看scala里面是个object,它这个里面并没有像我们想象的那种valueof的方法。
所以怎么办:
val commonCompare
2
= new CommonCompare(java.lang.
float
.valueof(1
.
1f),java.lang.
float
.valueof(2.1f))
}
//Int
println(commonCompare1.greater)
这个时候你会发现第二个方法通用性要比第一个好很多,只要写一份,只要他那边实现compare接口就可以用。
下面执行一下效果:
这还不算完。还有一个更简单的的方法:
val commonCompare
3
= new CommonCompare(1
.
1f, 2.1f) //
println(commonCompare
3
.greater)
想一下这样写可不可以?
很显然虽然语法能过但是是跑不起来的。因为1.1f并没有实现comparable,也就是说并不是我们这个子类。
这样运行仍然会报错:
但是又不想麻烦的写,我们要如何去写?
前面这个地方是可以指定一个类型的,看看它能不能搞定。
看一段源码:
Impact Predef这个包追进去看看里面有什么东西。打开过后,我们发现有大量的的东西都在里面。往下找,有好多implicit的隐式函数:
再往下看:
有个float 2 float:
意思是如果有一个x:float,可以转成java.long.float.
前面的float是scala里面的,后面的是Java的float。这样才实现了compare结构,他就是这么来的。
//第三种写法使用了隐式转换:
val commonCompare3 = new CommonCompare[java.lang.float]( 10.1f, 21.1f)
//Int
下面执行一下:
println(commonCompare1.greater)
这个语法第一用了上界,第二用了隐式转换,这个语法糖还是很高级的。
以上就是第一个案例。