zoukankan      html  css  js  c++  java
  • Scala学习之路 (八)Scala的隐式转换和隐式参数

    一、概念

    Scala 2.10引入了一种叫做隐式类的新特性。隐式类指的是用implicit关键字修饰的类。在对应的作用域内,带有这个关键字的类的主构造函数可用于隐式转换。

    隐式转换和隐式参数是Scala中两个非常强大的功能,利用隐式转换和隐式参数,你可以提供优雅的类库,对类库的使用者隐匿掉那些枯燥乏味的细节。 

    二、作用

    隐式的对类的方法进行增强,丰富现有类库的功能

    三、隐式参数

    1)关键字:implicat
    2)隐士的东西只能在object里面才能使用
    3)作用域

    四、隐式转换函数

    是指那种以implicit关键字声明的带有单个参数的函数。

    可以通过::implicit –v这个命令显示所有做隐式转换的类。

    四、隐士转换的发生的时机

    1、当一个对象去调用某个方法,但是这个对象并不具备这个方法

    (1)scala源码示例

    1是Int类型,从to方法看,Int应该有to方法

    打开Int类的源码查看,并没有Int本身并没有to方法,发现Int继承了AnyVal类

    查看AnyVal类,发现AnyVal类同样没有to方法,而AnyVal类继承了Any类

    Any类里面没有to方法,而在RichInt里面有to方法

    而在上面查看scala自动导入隐式转换函数时可以看到有Predef类的intWrapper方法,传入的参数是Int,返回的结果类型是RichInt

    (2)快学Scala示例值File和RichFile示例

    不使用隐式转换时,使用装饰模式进行读取

    import java.io.File
    
    import scala.io.Source
    
    class RichFile(val file : File) {
      //定义一个read方法,返回String类型
      def read():String = Source.fromFile(file.getPath).mkString
    }
    
    object RichFile{
      //隐式转换方法(将原有的File类型转成了file类型,在用的时候需要导入相应的包)
      //implicit def file2RichFile(file:File) = new RichFile(file)
    }
    
    object MainApp{
    
      def main(args: Array[String]): Unit = {
        val file = new File("D:\student.txt")
        //装饰模式,显示的增强(本来想实现:val contents = file.read(),但是却使用RichFile的方式,所以是显示的增强)
        val rf = new RichFile(file)
        val str = rf.read()
        print(str)
      }
    
    }

    使用隐式转换方式

    import java.io.File
    
    import scala.io.Source
    
    class RichFile(val file : File) {
      //定义一个read方法,返回String类型
      def read():String = Source.fromFile(file.getPath).mkString
    }
    
    object RichFile{
      //隐式转换方法(将原有的File类型转成了file类型,在用的时候需要导入相应的包)
      implicit def file2RichFile(file:File) = new RichFile(file)
    }
    
    object MainApp{
    
      def main(args: Array[String]): Unit = {
        //目的是使用File的时候不知不觉的时候直接使用file.read()方法,所以这里就要做隐式转换
        val file = new File("D:\student.txt")
        //导入隐式转换,._将它下满的所有的方法都导入进去了。
        import RichFile._
        //这里没有的read()方法的时候,它就到上面的这一行中的找带有implicit的定义方法
        val str = file.read()
        //打印读取的内容
        println(str)
      }
    
    }

    (3)超人示例

    class Man(val name:String)
    class SuperMan {
      def fly(): Unit ={
        println("我要上天")
      }
    }
    
    object SuperMan{
      //隐式转换,将Man转换为SuperMan
      implicit def man2SuperMan(man:Man)=new SuperMan
      def main(args: Array[String]): Unit = {
        new Man("灰太狼").fly
      }
    }

    2、调用某个方法的时候,这个方法确实也存在,存入的参数类型不匹配

     售票厅卖票

    老人和小孩是特殊人群,有单独的买票窗口

    //特殊人群(儿童和老人)
    class SpecialPerson(var name:String)
    //儿童
    class Children(var name:String)
    //老人
    class Older(var name:String)
    //青年工作者
    class Worker(var name:String)
    
    //特殊人群买票窗口
    class TicketHouse{
      def buyTicket(p:SpecialPerson): Unit ={
        println(p.name + "买到票了")
      }
    }
    
    object MyPredef{
      //隐式转换,将儿童转换为特殊人群
      implicit def children2SpecialPerson(c:Children)=new SpecialPerson(c.name)
      //隐式转换,将老人转换为特殊人群
      implicit def older2SpecialPerson(o:Older)=new SpecialPerson(o.name)
    
    }
    
    
    object TestBuyTicket{
      def main(args: Array[String]): Unit = {
        //导入MyPredef类中的所有隐式转换
        import MyPredef._
        val house = new TicketHouse
        //测试儿童买票
        val children = new Children("wangbaoqiang")
        house.buyTicket(children)
        //测试老人买票
        val older = new Older("xuzheng")
        house.buyTicket(older)
        //测试青年工作者买票
        val worker = new Worker("huangbo")
        //house.buyTicket(worker)//放开的话会报错
      }
    }

    3、视图边界

     人狗之恋

    class Person(val name : String) {
      def sayHello: Unit ={
        println("Hello, my name is " + name)
      }
      //2个人交朋友
      def mkFridens(p:Person): Unit ={
        sayHello
        p.sayHello
      }
    }
    
    class Student(name : String) extends Person(name)
    class Dog(val name : String)
    //聚会时2个人交朋友
    class Party[T <% Person](p1:Person,p2:Person){
      p1.mkFridens(p2)
    }
    
    object Test{
      //隐式转换,将狗转换成人
      implicit def dog2Person(dog:Dog):Person={
        new Person(dog.name)
      }
    
      def main(args: Array[String]): Unit = {
        val huangxiaoming = new Person("huangxiaoming")
        val angelababy = new Student("angelababy")
        new Party[Person](huangxiaoming,angelababy)
    
        println("------------------------------------------------")
    
        val erlangshen = new Person("erlangshen")
        val xiaotianquan = new Dog("xiaotianquan")
        new Party[Person](erlangshen,xiaotianquan)
      }
    }

  • 相关阅读:
    PHP 开发 APP 接口 --Redis篇
    PHP 开发 APP 接口--静态缓存篇
    PHP 开发 APP 接口 --JSON、XML结合篇
    PHP 开发 APP 接口 --JSION篇
    PHP 开发 APP 接口--XML篇
    程序员必须掌握的600个英语单词
    Memcache
    伪静态
    ob缓冲
    函数的使用顺序---TABLES,USING,CHANGING
  • 原文地址:https://www.cnblogs.com/qingyunzong/p/8877140.html
Copyright © 2011-2022 走看看