scala的隐式对象和隐式类

30 阅读1分钟

隐式对象

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

隐式类

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

基本代码

package imp

/*
* 隐式类
*
* 背景:有一个现成的类,它有一个方法。我们现在需要对这个类进行拓展:额外补充一个新方法。
*
* 但是:不允许直接修改原来的类的代码。
*
* 思路:
*   1. 补充一个新的类,把这个新的方法写到这个类中。
*   2. 补充一个隐式转换函数,把这个旧类转成新类。
*
* 隐式类!
*   1. class 前面加implicit
*   2. 入参就是要拓展功能的那个对象
*
 */
object imp05 {
  class User {
    def insertUser():Unit={
      println("添加一个新用户.......")
    }
  }

  implicit class UserExt(user:User) {
    def updateUser(): Unit = {
      println("修改用户......")
    }
  }
//  implicit def xxx(user:User):UserExt={
//    new UserExt
//  }

  def main(args: Array[String]): Unit = {
    val u1=new User()
    u1.insertUser()

    u1.updateUser()
  }
}

案例:判断手机号是否合法

package imp

/*
* 需求:
*   让所有的字符串都具备一个功能:检查自己是不是一个合法的手机号码?
*
*
 */
object imp06 {
  // 让所有的String对象,都有了一个新的方法 isPhone
  implicit class StrongString(s:String) {
    def isPhone():Boolean={
      val reg="^1[356789]\d{9}$".r
      reg.matches(s)
    }
  }

  def main(args: Array[String]): Unit = {
    val str=new String("13568394259")

    var str1="abandsfsdfs"

    // 判断是否是一个手机号
    if(str.isPhone){
      println(s"${str}是手机号")
    }else{
      println(s"${str}不是手机号")
    }
    if(str1.isPhone){
      println(s"${str1}是手机号")
    }else{
      println(s"${str1}不是手机号")
    }
  }
}

案例:让所有的整数都可以阶乘

package imp

/*
* 需求:
*   让所有的整数都具备一个功能:计算阶乘
*
*   n!=1*2*3*4*...*n
*
*   1. 目前的整数是没有具备这个功能的。
*
*   2. 拓展Int这个类
*
*
 */
import scala.language.postfixOps
object imp07 {
  implicit class StrongInt(n: Int) {
    def !(): Int = {
      //println("阶乘......")
      var s = 1
      for (i <- 1 to n) {
        s *= i
      }
      s
    }
  }
    def main(args: Array[String]): Unit = {
      var k = 5  //5*4*3*2*1=120

      // 计算k的阶乘
      printf(s"${k}的阶乘是:${k !}")
    }

}