scala开发快速入门 | 第七篇 隐式转换

隐式转换

它是scala的一种特殊的功能,它能将一种数据类型转换为另一种数据类型,然后这种数据类型将拥有另一种数据类型的所有方法。可以看成对类的增强。

隐式转换分为两种:

1)隐式转换函数

2)隐式转换值

隐式转换的关键字 implicit

隐式转换命名方式 one2one    

/*特殊人群*/
class SpecialPerson01(var name: String)
/*老人*/
class Older01(var name: String)
/*成年人*/
class Adult01(var name: String)
object ImplicitDemo01 {
  /*此方法是用来买特殊票的窗口*/
  def buySpeciaTicketlWindow(p: SpecialPerson01): Unit = {
    if (p != null) {
      println(p.name + "购买了一张特殊票!")
    } else {
      println("您不是特殊人群,请去正常窗口购票!")
    }
  }
  /*此方法的作用就是将 Order01或者Children01类型转为SpecialPerson01类型*/
  implicit def any2SpecialPerson01(any: Any):SpecialPerson01 = {
    if(any.isInstanceOf[Older01]) {
      val older01 = any.asInstanceOf[Older01]
      new SpecialPerson01(older01.name)
    }
    else{
      null
    }
  }
  def main(args: Array[String]): Unit = {
    val special = new SpecialPerson01("特殊人")
    val older01 = new Older01("老人")
    val adult = new Adult01("成年人")
    //    buySpeciaTicketlWindow(special)
    //    buySpeciaTicketlWindow(order) 无法将order对象作为buySpeciaTicketlWindow参数 类型不匹配
    /**
      * 那么如何将 orderchildren转为特殊人群呢?
      * 我们定义一个隐式转换函数然后可以使用隐式转换函数*/
    /**
      * 这里我们给buySpeciaTicketlWindow 传入的参数是Order01类型 为什么能够可以了呢?
      * scala中 它会自动去查找程序中会不会存在implicit关键字将 Order01类型转为SpecialPerson01类型
      * 如果存在那么将Order01自动的隐式转换为SpecialPerson01
      **/
    buySpeciaTicketlWindow(older01)
    buySpeciaTicketlWindow(adult)

  }
}

隐式转换对类的增强

class RichFile(var file: File) {

  def read(): Unit = {
    val content = Source.fromFile(file).mkString
    println(content)
  }
}

/*隐式转换对类的增强*/
class ImplicitDemo02 {

}

object ImplicitDemo02 {

  def main(args: Array[String]): Unit = {
    var file = new File("D:\\tmp\\h2o-28160\\h2ologs\\h2o_127.0.0.1_54321-4-warn")

    /** file想调用 RichFile类中的read方法 是无法调用的 */
    //    file.read()
    /** 为了能够让 file能够调用 RichFile类中的read方法 可以将file隐式转换为RichFile */

    file.read()//scala在程序中自动的查找看是否有隐式转换 将File转为RichFile

    implicit def file2RichFile(file: File): RichFile = {
      
      new RichFile(file)

    }
  }
}

隐式参数

scala方法中的参数被 implicit 关键字修饰那么这个参数就是隐式参数。

使用隐式参数,避免了的调用方法的时候每次传入相同的类型问题。

class SinPen {
  def write(content: String): Unit = {
    println(content)

  }
}

class ImplicitDemo03 {

}

object ImplicitDemo03 {
  def main(args: Array[String]): Unit = {
    //    每次调用sinForExam方法时候都会传入SinPen对象 我们可以使用隐式参数 避免这个问题
    val p = new SinPen
    sinForExam("ysj")(p)
    sinForExam("qff")(p)
    /*隐式参数的使用*/
    implicit val p2 = new SinPen
    sinForExam("spark")
    sinForExam("hive")

  }

  def sinForExam(name: String)(implicit p: SinPen): Unit = {
    p.write(name)

  }
}

扩大隐式转换作用域

以前书写隐式转换函数或者隐式转换值都是在本类中定义的,这样就会存在着局限性。为了避免这个局限性可以将隐式转换函数和隐式转换值定义在object对象中这样就可以扩大隐式转换的作用域,以后多个地方使用的话,我们直接使用import将对应的隐式转换函数或者值导入即可。

视图界定

/*视图界定
* 使用符号 <%   T<% Person 表示T只能是Person的子类 或者T能隐式转换成Person*/

class Person05(var name: String) {
  def sayHello() = {
    println("I am " + name)
  }

  def makeFriends(p: Person05): Unit = {
    sayHello()
    p.sayHello()
  }
}
class student05(name: String) extends Person05(name)

class Cat(var name: String) {
  def sayHello(): Unit = {
    println("miao miao is " + name)

  }
}
/*泛型T只能是Person05及其子类,或者T能够隐式转换成Person05类型*/
class Party[T <% Person05](p1: T, p2: T) {
  p1.makeFriends(p2)
}
object ImplicitDemo05 {
  def main(args: Array[String]): Unit = {
    /*T Person05的情形*/
    val p1 = new Person05("xiaoming")
    val p2 = new Person05("baby")
    val pty = new Party[Person05](p1, p2)

    /*T Person05子类的情形*/
    val s1 = new student05("ysj")
    val s2 = new student05("qff")
    val pty2 = new Party[student05](s1, s2)

    /**TCat的情形 会报错 因为Cat 不是Person05类型以及Person05的子类
      * 但是我们可以将Cat隐式转换为Person05*/
   /* val c1 = new Cat("ysj")
    val c2 = new Cat("qff")
    val pty3 = new Party[Cat](c1, c2)*/
  implicit  def cat2Person05(cat:Cat):Person05={
     new Person05(cat.name)
   }
    val c1 = new Cat("cat1")
    val c2 = new Cat("cat2")
    val pty3 = new Party[Cat](c1, c2)
  }
}



猜你喜欢

转载自blog.csdn.net/yangshaojun1992/article/details/80956925
今日推荐