【Scala】Scala之Object(一)

简介: 前面学习了Scala的Methods,接着学习Scala中的Object

一、前言


  前面学习了Scala的Methods,接着学习Scala中的Object


二、Object


  Object在Scala有两种含义,在Java中,其代表一个类的实例,而在Scala中,其还是一个关键字,本篇首先将会把object当成一个类的实例看待,展示如何将对象从一种类型转化为另一种类型,之后将展示如何创建单例对象,Scala中还存在包对象,在Scala中,经常有如下定义

type Throwable = java.lang.Throwable
type Exception = java.lang.Exception
type Error = java.lang.Error
type Seq[+A] = scala.collection.Seq[A]
val Seq = scala.collection.Seq

使用type定义可以使得代码更为简洁,可使用伴生对象来创建静态方法,并且伴生对象可以使得在创建类对象时不需要使用new关键字,如下所示

val siblings = List(Person("Kim"), Person("Julia"), Person("Kenny"))

2.1 对象转化

  1. 问题描述

  你需要将一个类的实例从一种类型转化为另一种类型,如动态创建对象

  2. 解决方案

  使用asInstanceOf方法进行类型转化,如下的lookup方法返回的对象将给转化为Recognizer对象 

val recognizer = cm.lookup("recognizer").asInstanceOf[Recognizer]

以上代码在Java中如下 

Recognizer recognizer = (Recognizer)cm.lookup("recognizer");

asInstanceOf方法是定义在Any类中的,所以任何类中都可以使用该方法

  3. 讨论

  在动态编程中,经常需要从一个类转化为另一个类,如在Spring框架中使用ApplicationContext文件来初始化Bean 

// open/read the application context file
val ctx = new ClassPathXmlApplicationContext("applicationContext.xml")
// instantiate our dog and cat objects from the application context
val dog = ctx.getBean("dog").asInstanceOf[Animal]
val cat = ctx.getBean("cat").asInstanceOf[Animal]

在进行数字类型转化时,也可以使用asInstanceOf方法

  2.png

  当需要与Java进行交互时,也可以使用asInstanceOf方法  

val objects = Array("a", 1)
val arrayOfObject = objects.asInstanceOf[Array[Object]]
AJavaClass.sendObjects(arrayOfObject)

 与Java类似,类型转化可能会抛出ClassCastException异常

  3.png

  可以使用try/catch来解决此问题

  2.2 与Java的.class对应的方法

  1. 问题描述

  当一个API需要你传递Class对象,在Java中,你可以使用.class,但是在Scala则行不通

  2. 解决方案

  使用Scala的classOf方法,如下所示  

val info = new DataLine.Info(classOf[TargetDataLine], null)

 在Java中则使用如下  

info = new DataLine.Info(TargetDataLine.class, null);

 classOf方法定义在Predef对象中,因此可以在没有import情况直接使用

  3. 讨论

  该方法可以让你开始学习反射,如下示例可以访问String类的方法

  4.png

  2.3 确定对象的类

  1. 问题描述

  在Scala中,你不需要显示的声明类型,你偶尔也想要打印一个对象的类或类型以明白Scala的工作机制

  2. 解决方案

  你可以使用对象的getClass方法来确定Scala为你自动赋值的类型,如当需要了解可变参数的工作流程时,可以调用getClass方法,得知不同情况,类型也不相同 

def printAll(numbers: Int*) {
    println("class: " + numbers.getClass)
}

当使用多个参数调用printAll方法和不使用参数调用printAll方法,其结果不相同

  5.png

  当处理Scala的XML库时,该方法非常有效,可以知道在不同情形下所处理的类,如下,<p>标签下包含了一个子类

  6.png

  当在<p>标签中添加<br/>标签后,其结果如下

  7.png

  3. 讨论

  若在IDE中无法得知对象的类型,可以使用getClass方法来获取对象类型

  8.png

  2.4 使用对象启动应用

  1. 问题描述

  你想要使用main方法来启动一个应用,或者为脚本提供一个入口

  2. 解决方案

  启动应用有两种方法,其一让类继承App,其二是定义一个对象并定义main方法

  对于第一种方法,其通用做法如下 

object Hello extends App {
    println("Hello, world")
}

 此时object内的语句会自动执行,第二种方法是定义main方法

object Hello2 {
    def main(args: Array[String]) {
        println("Hello, world")
    }
}    

3. 讨论

  上述两种方法中,都是通过object来启动应用的

  2.5 使用Object创建单例

  1. 问题描述

  你想要创建一个单例对象

  2. 解决方案

  使用object关键字来创建单例对象  

object CashRegister {
    def open { println("opened") }
    def close { println("closed") }
}

由于CashRegister被定义为成object,因此仅仅只有一个实例,被调用的方法就相当于Java中的静态方法,调用如下

object Main extends App {
    CashRegister.open
    CashRegister.close
}

在创建工具方法时,该方法同样有效 

import java.util.Calendar
import java.text.SimpleDateFormat
object DateUtils {
    // as "Thursday, November 29"
    def getCurrentDate: String = getCurrentDateTime("EEEE, MMMM d")
    // as "6:20 p.m."
    def getCurrentTime: String = getCurrentDateTime("K:m aa")
    // a common function used by other date/time functions
    private def getCurrentDateTime(dateTimeFormat: String): String = {
        val dateFormat = new SimpleDateFormat(dateTimeFormat)
        val cal = Calendar.getInstance()
        dateFormat.format(cal.getTime())
    }

 由于方法是定义在object中,因此可以直接使用DateUtils来调用这些方法,如同Java中调用静态方法 

DateUtils.getCurrentDate
DateUtils.getCurrentTime

 在使用actors时,单例对象可以产生可重用的消息,如果你有可以接受和发送消息的actor,你可以使用如下方法创建单例 

case object StartMessage
case object StopMessage

 这些对象将会被作为消息,并且可被传递到actor中  

inputValve ! StopMessage
outputValve ! StopMessage

3. 讨论

  当使用伴生对象时,一个类就既可以有非静态方法又可以有静态方法

  2.6 使用伴生对象创建静态成员

  1. 问题描述

  你想要为一个类创建实例方法和类方法,但是Scala中没有static关键字

  2. 解决方案

  在class中定义非静态成员,在object中定义静态成员,对象与类要有相同的名字并且位于同一个文件中,该对象称为伴生对象

  使用该方法可以让你创建静态成员(字段和方法) 

// Pizza class
class Pizza (var crustType: String) {
    override def toString = "Crust type is " + crustType
}
// companion object
object Pizza {
    val CRUST_TYPE_THIN = "thin"
    val CRUST_TYPE_THICK = "thick"
    def getFoo = "Foo"
}

 Pizza类和Pizza对象在同一个文件中(Pizza.scala),Pizza对象中的成员等效于Java类中的静态成员 

println(Pizza.CRUST_TYPE_THIN)
println(Pizza.getFoo)

你也可按照常规方法创建Pizza对象

var p = new Pizza(Pizza.CRUST_TYPE_THICK)
println(p)

3. 讨论

  class和object具有相同的名称并且在同一个文件中,class中定义的是非静态成员,object中定义的是静态成员

  class和其伴生对象可以互相访问对方的私有成员,如下面object的double方法可以访问class中的私有变量secret  

class Foo {
    private val secret = 2
}
object Foo {
    // access the private class field 'secret'
    def double(foo: Foo) = foo.secret * 2
}
object Driver extends App {
    val f = new Foo
    println(Foo.double(f)) // prints 4
}

 如下的class类中的非静态方法可以访问伴生对象中的静态私有变量 

class Foo {
    // access the private object field 'obj'
    def printObj { println(s"I can see ${Foo.obj}") }
}
object Foo {
    private val obj = "Foo's object"
}
object Driver extends App {
    val f = new Foo
    f.printObj
}


目录
相关文章
|
6月前
|
分布式计算 Java Scala
Scala:面向对象、Object、抽象类、内部类、特质Trait(二)
Scala:面向对象、Object、抽象类、内部类、特质Trait(二)
91 0
|
算法 编译器 Scala
【Scala】Scala之Object(二)
前面学习了Scala的Methods,接着学习Scala中的Object
124 0
【Scala】Scala之Object(二)
|
Scala Java
[Scala]Scala学习笔记五 Object
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SunnyYoona/article/details/76423770 1.
1142 0
|
1月前
|
分布式计算 大数据 Java
大数据-87 Spark 集群 案例学习 Spark Scala 案例 手写计算圆周率、计算共同好友
大数据-87 Spark 集群 案例学习 Spark Scala 案例 手写计算圆周率、计算共同好友
49 5
|
1月前
|
分布式计算 关系型数据库 MySQL
大数据-88 Spark 集群 案例学习 Spark Scala 案例 SuperWordCount 计算结果数据写入MySQL
大数据-88 Spark 集群 案例学习 Spark Scala 案例 SuperWordCount 计算结果数据写入MySQL
48 3
|
1月前
|
消息中间件 分布式计算 NoSQL
大数据-104 Spark Streaming Kafka Offset Scala实现Redis管理Offset并更新
大数据-104 Spark Streaming Kafka Offset Scala实现Redis管理Offset并更新
38 0
|
1月前
|
消息中间件 存储 分布式计算
大数据-103 Spark Streaming Kafka Offset管理详解 Scala自定义Offset
大数据-103 Spark Streaming Kafka Offset管理详解 Scala自定义Offset
75 0
|
1月前
|
分布式计算 大数据 Java
大数据-86 Spark 集群 WordCount 用 Scala & Java 调用Spark 编译并打包上传运行 梦开始的地方
大数据-86 Spark 集群 WordCount 用 Scala & Java 调用Spark 编译并打包上传运行 梦开始的地方
20 1
大数据-86 Spark 集群 WordCount 用 Scala & Java 调用Spark 编译并打包上传运行 梦开始的地方
|
1月前
|
SQL 分布式计算 Java
大数据-96 Spark 集群 SparkSQL Scala编写SQL操作SparkSQL的数据源:JSON、CSV、JDBC、Hive
大数据-96 Spark 集群 SparkSQL Scala编写SQL操作SparkSQL的数据源:JSON、CSV、JDBC、Hive
33 0