隐式对象
定义:
隐式对象是一个带有implicit关键字的单例对象,它可以用于提供某种类型的实例以供隐式转换使用。隐式对象通常用于将某个类或trait的实例隐式地注入到方法中。
示例代码:
case class DatabaseConfig( driver: String, url: String)
implicit object MySqlDefaultConfig extends DatabaseConfig(
"com.mysql.cj.jdbc.Driver",
"jdbc:mysql://localhost:3306/mydb")
def getConnection(implicit config: DatabaseConfig): Unit = {
println(config.url)
}
getConnection
隐式类
-
目标:已有一个写好的类,要求在不修改这个类的源代码的情况下,拓展这个类的新功能
-
思路:
- 补充定义一个新类,在这个新类中提供新方法
- 提供一个隐式转换函数,把之前旧类对象转换成这个新类对象
示例代码:
/*
目标:已有一个写好的类,要求在不修改这个类的源代码的情况下,拓展这个类的新功能
思路:
1.补充定义一个新类,在这个新类中提供新方法
2.提供一个隐式转换函数,把之前旧类对象转换成这个新类对象
*/
object day53 {
class User() {
def insertUser():Unit = {
println("insertuser......")
}
}
class UserStrong() {
def updateUser():Unit = {
println("updateuser......")
}
}
implicit def xxxxx(user:User):UserStrong = {
println("自动调用隐式转换函数......")
new UserStrong
}
def main(args: Array[String]): Unit = {
val u1 = new User()
u1.insertUser()
// val u2 = new UserStrong()
u1.updateUser()
// u2.updateUser()
}
}
作用域
先说一个不能放的位置:implicit 不能放在顶级作用域(不能放在类的外边)看如下代码,就会报错
implicit class UserExt(user: User) {
def updateUser(): Unit = {
println("updateUser")
}
}
class User {
def insertUser(): Unit = {
println("insertUser")
}
}
object T1 extends OtherClass {
def main(args: Array[String]): Unit = {
val u1 = new User()
u1.insertUser()
u1.updateUser()
}
}
在实际的操作过程中,我们建议把它定义在如下两个地方:
- 包对象。这样在这个包下的所有类和对象中都可以使用,并且不需要额外的引入语句。
- 一个单独的文件定义中。这样在其他需要的位置就可以直接导入,然后使用。
package implications
object Implications{
implicit def double2Int (x: Double):Int { x.toInt }
}
在其他需要使用的地方导入: import implication.Implications._
案例:
一个字符串具备一个功能,判断是否是一个合法的手机号
/*
目标:让人一样一个字符串具备一个功能,判断是否是一个合法的手机号
String类是系统提供的,并没有isPhone()方法
现在要在不修改String类的情况下,添加这个方法
*/
object day54 {
implicit class StrongString(s:String) {
def isPhone:Boolean={
val reg="^1[35678]\\d{9}$".r
reg.matches(s)
}
def isIDCard: Boolean = {
val Reg1 = "^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$".r
Reg1.matches(s)
}
}
def main(args: Array[String]): Unit = {
val str=new String("13827339067")
println(str.isPhone)
println("134567891a".isPhone)
println("130567891a".isPhone)
println("421022200901203625".isIDCard)
println("42102220070118368a".isIDCard)
}
}
运行结果如下:
true
false
false
true
false
让任意一个整数具备一个功能:计算阶乘
package imp
import scala.language.postfixOps
object day55 {
/*
目标:让任意一个整数具备一个功能:计算阶乘
*/
implicit class StrongInt(n:Int) {
def !! :Int = {
var rst = 1
for(i <- 1 to n) {
rst *= i
}
rst
}
}
def main(args: Array[String]): Unit = {
println(4!!) // 24
println(5!!) // 120
}
}
运行结果如下:
24
120