zoukankan      html  css  js  c++  java
  • Scala 对象

    1. 单例对象

    对于任何你在Java中会使用单例对象的地方, 在scala中都可以使用对象来实现;
    scala字段没有静态方法或者静态字段, 可以使用object语法结构达到同样的效果,对象(object)定义了某个类的单个实例;
    对象构造器在对象第一次被使用时调用, 如果一个对象从来没有被使用过, 其构造器也不会被执行;
    对象从本质本质上可以拥有类的所有特质, 只有一个例外, 你不能提供构造器参数

    scala中对象的常见用法是:

    • 作为存放工具函数或常量的地方
    • 高效的共享单个不可变实例的地方
    • 需要某个单例来协调某个服务时(参考单例模式)

    2. 伴生对象(Companion Object)

    在Java中你通常会用到既有实例方法又有静态方法的类, 在Scala中可以通过与类同名的伴生对象达到同样目的.

    类和她的伴生对象必须存在同一个源文件中(.scala), 可以相互访问私有属性, 类可以访问其伴生对象, 不过并不是因为在一个作用域中, 比如说 类HappyObject通过HappyObject.newUniqueName 而不是newUniqueName直接访问伴生对象的方法

    class HappyObject {
      val id = HappyObject.newUniqueName()
      private var balance = 0.0
    
      def deposit(amount: Double): Unit = {
        balance += amount
      }
    }
    
    // 伴生对象
    object HappyObject {
      private var lastNumber = 0
    
      def newUniqueName()  {
        lastNumber += 1
        lastNumber
      }
    }
    
    

    3. apply方法

    当遇到下面的情况时, apply方法就会被调用,

    Object(参数1, 参数2, ...)
    通常这样返回的是类的伴生对象

    比如说Array对象定义了apply方法, 让我们可以通过下面的方法创建数组
    Array("happy" , "goodday")

    这里你可能问为什么不用构造器, 看到下面的嵌套表达式, 就可以看到省去new关键字会方便很多
    Array(Array("happy", "smile") , Array("goodday", "shinning"))

    △: Array(10) VS new Array(10)
    Array(10) 调用的是伴生对象的apply方法, 输出一个单个元素的Array[Int];
    new Array(10) 调用的是构造器this(100), 输出包含10个null元素的Array[Nothing]

    一般在apply方法中调用伴生类的构造器

    4. 应用程序对象

    每个scala程序都必须从一个对象的main方法开始
    这个方法的类型是 Array[String] => Unit

    object Happy {
        def main(args: Array[String]) {
            print("hello world")
         }
    }
    

    除了每次提供自己的main方法之外, 也可以继承App特质, 然后将程序代码写入构造方法体内;如果你在调用应用程序时设置scala.time选项的话, 控制台会显示程序执行时间; 如果需要命令行参数, 可以通过args属性得到.

    object HappyApp extends App {
    
      if(args.length > 0)  println("happy" + args(0))
      else  println("happy ending")
    }
    

    scalac HappyApp.scala
    scala -Dscala.time HappyApp start

    5. 枚举

    Scala对象没有枚举类型, 不过标准类库有一个scala.Enumeration助手类, 用于产生枚举

    枚举对象的枚举值类型是一个内部类对象, 包含两个属性id名称,这两个属性都可以设置,你也可以不设置或者设置1个

    • 设置id: 如果不指定, id在前一个id的基础上加1, 从零开始, 指定id时确保id之前没有被用过,不能重复;
    • 设置名称: 不设置名称的话, 默认名称是字段名

    5.1 使用方法

    定义一个继承Enumeration类的对象(比如叫Enum),并以Value方法调用初始化枚举中的所有可选值, 每次调用Value方法都会返回内部类(也叫Value)的新对象, 所以枚举值的类型是Enum.Value,而不是Enum

    常用方法说明:

    枚举值 说明
    Enum.green 获取枚举值
    Enum.green.id 获取枚举值ID
    Enum.green.toString 获取枚举值名称
    Enum.values.values 返回所有的枚举值的集合
    Enum(2) 通过 id 获取枚举值(调用Enumeration.apply)
    Enum.withName("green") 通过名称获取枚举值
    object Enum extends Enumeration {
      val red, yellow, green = Value
      val blue = Value(10, "hi, my color is blue")
    
      def main(args: Array[String]): Unit = {
    
        println(Enum.values)
        println(Enum.green.toString)
        println(Enum.green.id)
    
        println(Enum(10))
        println(Enum.withName("hi, my color is blue"))
        
        println(Enum.green.getClass.getName)
    
      }
      
     /*output:
    Enum.ValueSet(red, yellow, green, hi, my color is blue)
    green
    2
    hi, my color is blue
    hi, my color is blue
    scala.Enumeration$Val
     */
    }
    

    5.2 类型别名

    通过Enum.green的方式引用枚举值, 如果枚举对象的名字太长的话, 就会变得冗长, 可以通过下面方式引用枚举值

    import Enum._
    

    枚举值的类型是Enum.Value, 而不是Enum(Enum是握有这些值的对象), 所以有人推荐增加一个类型别名, 但是仅当会用import语句时这样做才有意义

    object Enum extends Enumeration {
    
      type Enum = Value
      
      val red, yellow, green = Value
      val blue = Value(10, "hi, my color is blue")
    

    现在Enum.Enum也可以表示枚举值的类型

    import chap04.Enum._
    object ImportEnum {
    
      def main(args: Array[String]): Unit = {
        val stop: Enum = blue
        println(blue)
    
      }
    }
    
    //output:  hi, my color is blue
    
  • 相关阅读:
    熔断器Hystrix
    面向对象
    基础语法
    为什么需要定义数据类型???
    集成Ribbon的客户端调用工具——Feign
    Ribbon实现客户端负载均衡
    入门神经网络-Python 实现(下)
    代码视角-神经网络-Python 实现(上)
    归纳方法
    神经网络-反向传播BP算法推导
  • 原文地址:https://www.cnblogs.com/nowgood/p/Scalaobject.html
Copyright © 2011-2022 走看看