scala之对象
来源:互联网 发布:苹果越狱会清除数据吗 编辑:程序博客网 时间:2024/06/05 23:05
单例对象
Scala没有静态方法或静态字段,你可以用object这个语法结构来达到同样的目的。对象定义了某个类的单个实例,包含你想要的特性。如,
object Number { private var num = 0; def newUniqueNum() = { num += 1 num } def main(args: Array[String]) { println(Number.newUniqueNum()) //打印1 }}
注:Scala的单例对象和Java中的静态方法/字段调用方式一致。在Scala中,对象的构造器在该对象第一次被使用时调用,若一个对象从未被使用,那么其构造器也不会被执行。对象本质上可以拥有类的所有特性-它甚至可以扩展其它类或特质,但是你不能提供构造器参数。
Scala单例对象使用场景
1.作为存放工具函数或常量的地方
2.高效共享单个不可变实例
3.需要单个实例来协调某个服务时(可参考单例模式)
伴生对象
在Java或C++中,你通常会用到即有实例方法又有静态方法的类。在Scala中,你可以通过类和与类同名的“伴生”对象来达到同样的目的。如
class Num { private val id = Num.newUniqueNum private def test() = {}}object Num { private var num = 0 new Num().test() private def newUniqueNum = {num += 1; num}}注:类和它的伴生对象可以相互访问私有特性;它们必须存在于同一个源文件中;类的伴生对象可以被访问,但并不在作用域中,Num类必须通过Num.newUniqueNum而不是直接用newUniqueNum来调用伴生对象的方法。
扩展类或特质的对象
一个对象可以扩展类以及一个或多个特质,其结果是一个扩展了指定类以及特质的类的对象,同时拥有在对象中给出的所有特性。一个有用的场景是给出可被共享的缺省对象。举例在来说,考虑在程序中引入一个可撤销动作的类,默认情况下什么都不做,对于这个行为你只需要一个实例即可,可通过对象扩展类实现。如下,
//定义供扩展的抽象类abstract class UndoableAction(val description : String) { def undo() : Unit def redo() : Unit}//DoNthingAction扩展自UndoableAction,默认情况下什么都不做。object DoNothingAction extends UndoableAction("Do nothing") { override def undo() {} override def redo() {}}
注:DoNothingAction对象可以被所有需要这个缺省行为的地方共用。
apply方法
我们通常会定义使用对象的apply方法。当遇到如下形式的表达式时,apply方法就会被调用:
Object(参数1, ..., 参数N)
通常,这样一个apply方法返回的是伴生类的对象。举例来说,Array对象定义了apply方法,让我们可以用下面这样的表达式来创建数组:
Array("a","b","c")
为什么我们不使用构造器呢?对于嵌套表达式而言,省去new关键字会方便很多。如,Array(Array(1,7), Array(2,6))。
我们来看一个示例:
class Account(val id: Int, initBalance: Double) { private var balance = initBalance def printTe() = println(balance)}object Account { def apply(initBalance: Double) = { new Account(1, initBalance) }}object Test { def main(args: Array[String]) { val account = Account(2.0) account.printTe }}注:输出结果为2.0。
应用程序对象
每个Scala程序都必须从一个对象的main方法开始,这个方法的类型为Array[String] => Unit。如,object Test { def main(args: Array[String]) { println("Hello, World!") }}注:输出结果为Hello, World!。
除了每次都提供自己的main方法外,你也可以扩展App特质,然后将程序代码翻入构造器方法体内。如,
object Hello extends App { println("Hello, World!")}注:输出结果为Hello, World!。
如果你需要命令行参数,则可以通过args属性得到,如
object Hello extends App { if(args.length > 0){ println("Hello, " + args(0)) } else{ println("Hello, World!") }}在类文件目录下执行如下命令
scalac Hello.scalascala -Dscala.time Hello Ming注:输出结果为Hello, Ming。如果在你在调用该程序时设置了scala.time选项的话,程序退出时会输出消耗的时间。App特质扩展自另一个特质DelayedInit,编译器对该特质有特殊处理。所有带有该特质的类,其初始化方法都会被挪到delayedInit方法中。App特质的main方法捕获到命令行参数,调用delayedInit方法,并且还可以根据要求打印消耗的时间。
枚举
和Java或C++不同,Scala并没有枚举类型。但是,标准库提供了一个Enumeration助手类,可以用于产出枚举类。例如,定义一个扩展Enumeration类的对象并以Value方法调用初始化枚举中的所有可选值。示例如下,
object Color extends Enumeration { val Red, Yellow, Green = Value //等同于:val Red = Value; val Yellow = Value; val Green = Value;}
注:上述示例定义了三个字段:Red、Yellow、Green,然后用Value调用将它们初始化。每次调用Value方法都返回内部类的新实例,该内部类也叫做Value。或者你也可以向Value方法传入ID、名称或者两个参数都传。如果不指定,则ID在将前一个枚举值的基础上加一,从零开始。缺省字段名称为字段的名。定义完成后,你就可以用Color.Red、Color.Yellow、Color.Green来引用枚举值了。如果这些变得冗长繁琐,则可以通过import Color._语句直接引入枚举类,然后直接调用Red等字段即可。记住枚举的类型是Color.Value而不是Color,后者是握有这些值的对象。
完整示例1:
object Color extends Enumeration { val Red = Value(0, "Red") val Yellow = Value("Yellow") val Green = Value("Green")}object TestEnum { def main(args: Array[String]): Unit = { for(color <- Color.values) { if(color.id == 2){ print(color.id + ": " + color) } else{ print(color.id + ": " + color + ",") } } }}注:输出结果为0: Red,1: Yellow,2: Green。
完整示例2:
object Color extends Enumeration { val Red = Value(0, "Red") val Yellow = Value("Yellow") val Green = Value("Green")}import Color._object TestEnum { def main(args: Array[String]): Unit = { for(color <- values) { if(color.id == 2){ print(color.id + ": " + color + ".") } else{ print(color.id + ": " + color + ",") } } }}注:输出结果为0: Red,1: Yellow,2: Green。上述示例中,你可以直接使用Red、Yellow、Green。
完整示例3:
object Color extends Enumeration { type Color = Value //定义类型别名 val Red = Value(0, "Red") val Yellow = Value("Yellow") val Green = Value("Green")}import Color._object action { def doWhat(color: Color) = { if(color == Red) "stop" else if(color == Yellow) "hurry up" else "go" }}object TestEnum { def main(args: Array[String]) { println(action.doWhat(Color.Green)) }}
注:输出结果为go。上述示例中使用type关键字定义类型别名,则该枚举的类型变成了Color.Color。
完整示例4:
object Color extends Enumeration { type Color = Value val Red = Value(0, "Red") val Yellow = Value("Yellow") val Green = Value("Green")}object TestEnum { def main(args: Array[String]) { print(Color(0) + ":" + Color.withName("Yellow")) }}注:输出结果为Red:Yellow。其中,Color(0)将调用Enumeration.apply。
- [scala之五]对象
- scala基础之对象
- scala之对象
- Scala之旅-面向对象
- scala之函数式对象
- Scala基础知识之伴生对象
- Scala面向对象编程之对象
- Scala学习笔记之面向对象
- Scala学习笔记之面向对象
- Scala学习之路----面向对象编程
- Scala之伴生类,伴生对象
- Scala入门学习之【类,对象,继承】
- Scala对象
- Scala 对象
- Scala对象
- scala对象
- Scala对象
- Scala学习—面向对象编程之对象
- Tensorflow介绍
- php 数据结构概述
- Apache Kylin的Cube分析
- Dubbo+Zookeeper+Maven+Idea 入门搭建笔记
- 2017 ACM/ICPC Asia Regional Shenyang Online
- scala之对象
- php实现无限极分类
- matter.js学习笔记(二)--Composites.stack()分析
- NDK r12b下编译安卓FFmpeg arm64架构出现的奇葩问题
- iOS 局部跑马灯效果实现
- mysql 练习
- 项目导入时报错:The import javax.servlet.http.HttpServletRequest cannot be resolved
- C/S与B/S
- stm32 can中断通信