scala的隐式对象和隐式类

34 阅读3分钟

(一)隐式对象

隐式对象是一个带有implicit关键字的单例对象,它可以用于提供某种类型的实例以供隐式转换使用。隐式对象通常用于将某个类或trait的实例隐式地注入到方法中。

(二)隐式类

背景:有一个现有的类。现在我们需要对这个类的功能进行拓展,额外补充一个方法。但是,不允许直接修改原来的类的代码。

假设这里有一个类User,它的内部有一个方法 insertUser。

我们的基本思路是:再写一个类,然后在其中补充一个方法,然后让当前的类去使用这个方法。

思路如下:function 是一个函数,而构造函数也是函数,并且函数的名称并不敏感,只需要实现把一种类型,转换为另一种类型,就可以了。

最后:把implicit 加在类的前面,就是隐式类。

package imp

/*
 *目标:已有一个写好的类,要求在不修改这个类的源代码的情况下,拓展这个类的新功能!
 *
 * 思路:
 *   1.补充定义一个新类,在这个新类中提供新方法!
 *   2.提供一个隐式转换函数,把之前旧类对象转换成这个新类对象。
 *
 * 隐式类。
 * implicit class
 *
 * 作用:在不改变原来的基础之后,增加新的功能
 */

object imp07 {

  class User() {
    def inserUser():Unit =
    println("inserUser......")
  }
  implicit class UserStrong(user:User) {
    def updateUser(): Unit = {
      println("updateUser......")
    }
  }

//  implicit def xxxx(user:User):UserStrong = {
//    println("自动调用隐式转换函数")
//    new UserStrong()
//  }

  def main(args: Array[String]): Unit = {
    val u1 = new User()
    // val u2 = new UserStrong()
    u1.inserUser()
    // u2.updateUser()
  }
}

image.png

案例:验证身份证号:

package imp

/*
 *目标:让任意一个字符串具备一个功能:判断是否是一个合法的手机号。
 *
 * String类是系统提供的,并没有isPhone这个方法。
 * 现在就要去在不修改String类的情况下,增加这个方法。
 */

object imp08 {

  implicit class StrongString(s:String) {
    def isPhone():Boolean = {
      val reg = "^1[345678]\d{9}$".r
      reg.matches(s)
    }

    def isIDCard(): Boolean = {
      val idReg = "^\d{17}[0-9Xx]$".r
      idReg.matches(s)
    }
  }
  def main(args: Array[String]): Unit = {
    val str = new String("18434876539")
//    val str = "18434876539"
//    str.isPhone // 判断自己是否是一个合法的手机号,返回值是boolean。true,false
    println(str.isPhone)
    println("16587463579".isPhone())
    println("13987665436".isPhone())
    println("420881200603273465".isIDCard) // true
    println("42088120060327346a".isIDCard) // false
  }
}

image.png

案例:计算阶乘

需求说明:给一个所有的整数添加一个功能,例如:

3!= 3 *2 * 1

println(3!) // 输出6

package imp

import scala.language.postfixOps
/*
 *目标:让任意一个整数具备一个功能,计算阶乘
 * n!= 1*2*3*...*n
 * 5! = 1*2*3*4*5 = 120
 *
 */

object imp09 {
  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
  }
}

image.png