转换

26 阅读3分钟
package imp

object imp04 {
  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()
    // val u2 = new UserStrong()
    u1.updateUser()
    // u2.updateUser()
  }
}

1. 包声明与对象定义

scala

package imp  // 声明代码所在的包名为imp

object imp04 {  // 定义一个单例对象imp04,Scala程序的入口需要放在object中
  • package imp:代码组织方式,类似 Java 的包,用于区分不同模块的代码。
  • object imp04:Scala 的单例对象,既是类的定义也是实例,main方法必须放在object中才能作为程序入口。

2. User 类定义

scala

class User() {
  def insertUser():Unit = {
    println("insertUser......")
  }
}
  • 定义一个普通的User类,里面只有一个insertUser方法,功能是打印字符串,返回值Unit等价于 Java 的void
  • 这个类本身没有updateUser方法。

3. UserStrong 类定义

scala

class UserStrong() {
  def updateUser():Unit = {
    println("updateUser......")
  }
}
  • 定义另一个类UserStrong,包含updateUser方法,功能是打印字符串。
  • 这个类和User类没有继承关系,是完全独立的。

4. 隐式转换函数

scala

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

这是整个代码的核心,逐行解释:

  • implicit:关键字,标记这是一个隐式转换函数,Scala 编译器会在需要时自动调用这个函数。
  • def xxxxx(user:User):函数名是xxxxx(可以自定义),参数是User类型的对象。
  • :UserStrong:函数返回值是UserStrong类型。
  • 函数体:先打印 “自动调用隐式转换函数......”,然后创建并返回一个UserStrong的新实例。

5. main 方法(程序入口)

scala

def main(args:Array[String]): Unit = {
  val u1 = new User()  // 创建User类的实例u1
  // val u2 = new UserStrong()  // 注释掉的代码,原本用于创建UserStrong实例
  u1.updateUser()      // 核心:调用u1的updateUser方法(但User类本身没有这个方法)
  // u2.updateUser()  // 注释掉的代码,原本用于调用UserStrong的updateUser方法
}

执行逻辑:

  1. 创建User实例u1u1本身只有insertUser方法。
  2. 执行u1.updateUser()时,编译器发现User类没有updateUser方法。
  3. 编译器会在当前作用域中查找隐式转换函数,发现implicit def xxxxx(user:User):UserStrong可以把User转换成UserStrong
  4. 编译器自动调用这个隐式转换函数,把u1转换成UserStrong实例。
  5. 调用转换后的UserStrong实例的updateUser方法。

代码执行结果

运行这段代码,控制台会输出:

plaintext

自动调用隐式转换函数......
updateUser......

总结

  1. 核心机制:Scala 的隐式转换能让一个类的对象 “借用” 另一个类的方法,无需继承或修改原类代码,实现了灵活的类扩展。
  2. 执行逻辑:当调用对象没有的方法时,编译器会自动查找匹配的隐式转换函数,将原对象转换成有该方法的对象,再执行方法。
  3. 关键关键字implicit是触发隐式转换的核心,它让编译器自动完成类型转换,简化代码编写。