[Scala]Scala学习笔记五 Object
1. 单例对象
Scala没有静态方法或静态字段,可以使用object来达到这个目的,对象定义了某个类的单个实例:
object Account{
private var lastNumber = 0
def newUniqueNumber () = {lastNumber += 1; lastNumber}
}
当你在应用程序中需要一个新的唯一账号时,调用Account.newUniqueNumber()即可.对象的构造器在该对象第一次被使用时调用.在本例中,Account的构造器在Account.newUniqueNumber的首次调用时执行.如果一个对象从未被使用,那么起构造器也不会被执行.
对象本质上可以拥有类的所有特性,但是不能提供构造器参数.
在Scala中可以用对象来实现:
- 作为存放工具函数或常亮的地方
- 高效的共享单个不可变实例
- 需要用单个实例来协调某个服务时(参考单例模式)
2. 伴生对象
在Java中,通常会用到既有实例方法又有静态方法的类,在Scala中,可以通过类和类同名的"伴生"对象来达到同样的目的:
class Account{
val id = Account.newUniqueNumber()
private var balance = 0.0
def deposit(amount : Double) { balance += amount }
...
}
// 伴生对象
object Account{
private var lastNumber = 0
def newUniqueNumber () = {lastNumber += 1; lastNumber}
}
类和它的伴生对象可以相互访问私有特性.它们必须在同一个源文件中.
3. apply方法
我们通常会定义和使用对象的apply方法.当遇到如下形式的表达式时,apply方法就会被调用:
Object(参数1,参数2,...,参数N)
通常,这样一个apply方法返回的是伴生类的对象. 举例来说,Array对象定义了apply方法,让我们可以用下面这样的表达式来创建数组:
Array("Mary", "had", "a", "little", "lamb")
不使用构造器,而是使用apply方法,对于使用嵌套表达式而言,省去new关键字会方便很多:
Array(Array(1,7), Array(2,9))
下面有一个定义apply方法的示例:
class Account private (val id :Int, initialBalance: Double){
private var balance = initialBalance
...
}
// 伴生对象
object Account{
def apply(initialBalance : Double){
new Account(newUniqueNumber(), initialBalance)
}
...
}
这样我们就可以使用如下方式创建账号了:
val acct = Account(1000.0)
4. 应用程序对象
每个Scala程序都必须从一个对象的main方法开始,这个方法的类型为Array[String]=>Unit:
object Hello{
def main(args: Array[String]){
println("Hello world!")
}
}
除了每次都提供自己main方法外,你可以扩展App特质,然后将程序代码放入构造器方法体内:
object Hello extends App{
println("Hello world!")
}
如果需要命令行参数,则可以通过args属性得到:
object Hello extends App{
if(args.length > 0){
println("Hello, " + args(0))
}
else{
println("Hello world!")
}
}
5. 枚举
不同于Java,Scala中没有枚举类型,需要我们通过标准库类Enumeration来实现:
object BusinessType extends Enumeration{
var FLIGHT, HOTEL, TRAIN, COACH = Value
}
继承Enumeration类,实现一个BusinessType对象,并以Value方法调用初始化枚举中的所有可选值.在这里我们定义了4个业务线类型,然后用Value调用它们初始化.
每次调用Value方法都返回内部类的新实例,该内部类也叫做Value.或者,可以向Value方法传入ID,名称:
val FLIGHT = Value(0, "FLIGHT")
val HOTEL = Value(10) // 名称为"HOTEL"
val TRAIN = Value("TRAIN") // ID为11
如果不指定ID,ID为上一个枚举值上加一,如果不指定名称,名称默认为字段名.定义完成后,可以使用BusinessType.FLIGHT,BusinessType.HOTEL,BusinessType.TRAIN等来引用:
def businessHandle(business: BusinessType.Value): Unit ={
if(business == BusinessType.FLIGHT){
println("this is a flight behavior")
}
else if(business == BusinessType.HOTEL){
println("this ia a hotel behavior")
}
}
def main(args: Array[String]): Unit = {
val business = BusinessType.FLIGHT
businessHandle(business) // this is a flight behavior
}
如果觉的BusinessType.FLIGHT比较冗长繁琐,可以使用如下方式引入枚举值:
import BusinessType._
使用时直接使用枚举值名称即可:
def businessHandle(business: BusinessType.Value): Unit ={
if(business == FLIGHT){
println("this is a flight behavior")
}
else if(business == HOTEL){
println("this ia a hotel behavior")
}
}
记住枚举值的类型是BusinessType.Value而不是BusinessType,后者是拥有这些值的对象,可以增加一个类型别名:
object BusinessType extends Enumeration{
type BusinessType = Value
var FLIGHT, HOTEL, TRAIN, COACH = Value
}
如下使用:
def businessHandle(business: BusinessType): Unit ={
if(business == FLIGHT){
println("this is a flight behavior")
}
else if(business == HOTEL){
println("this ia a hotel behavior")
}
}
枚举值的ID可以通过id方法返回,名称通过toString方法返回:
val business = FLIGHT
println("ID:" + business.id + " name:" + business.toString) // ID:0 name:FLIGHT
可以通过如下方式输出所有的枚举值:
for(business <- BusinessType.values){
println("ID:" + business.id + " name:" + business.toString)
}
ID:0 name:FLIGHT
ID:1 name:HOTEL
ID:2 name:TRAIN
ID:3 name:COACH
你也可以通过枚举的ID或名称来进行查找定位:
val FLIGHT1 = BusinessType(0)
println("ID:" + FLIGHT1.id + " name:" + FLIGHT1.toString)
val FLIGHT2 = BusinessType.withName("FLIGHT")
println("ID:" + FLIGHT2.id + " name:" + FLIGHT2.toString)
ID:0 name:FLIGHT
ID:0 name:FLIGHT
[Scala]Scala学习笔记五 Object的更多相关文章
- Scala入门学习笔记三--数组使用
前言 本篇主要讲Scala的Array.BufferArray.List,更多教程请参考:Scala教程 本篇知识点概括 若长度固定则使用Array,若长度可能有 变化则使用ArrayBuffer 提 ...
- Learning ROS for Robotics Programming Second Edition学习笔记(五) indigo computer vision
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...
- go微服务框架kratos学习笔记五(kratos 配置中心 paladin config sdk [断剑重铸之日,骑士归来之时])
目录 go微服务框架kratos学习笔记五(kratos 配置中心 paladin config sdk [断剑重铸之日,骑士归来之时]) 静态配置 flag注入 在线热加载配置 远程配置中心 go微 ...
- C#可扩展编程之MEF学习笔记(五):MEF高级进阶
好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...
- (转)Qt Model/View 学习笔记 (五)——View 类
Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ...
- java之jvm学习笔记五(实践写自己的类装载器)
java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...
- Typescript 学习笔记五:类
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
- ES6学习笔记<五> Module的操作——import、export、as
import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ...
- muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor
目录 muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor Connector 系统函数connect 处理非阻塞connect的步骤: Connetor时序图 Accep ...
随机推荐
- win10 安装 tensorflow 并运行helloworld
win10 安装 tensorflow 并运行helloworld 折腾了一下,在win10上成功安装tensorflow. 1 下载安装python,注意一定要是64位(比如python-3.5 ...
- 20145103《JAVA程序设计》第十周学习总结
网络编程 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事情就是把数据发送到指定的位置,或者接收到指定的数据,这个就是狭义的网络编程范畴.在发送和接收数据时,大部分的程序设 ...
- Hive Shell常用操作
1.Hive非交互模式常用命令: 1) hive -e:从命令行执行指定的HQL,不需要分号: % hive -e 'select * from dummy' > a.txt 2) hive – ...
- BZOJ 3192: [JLOI2013]删除物品 奇淫技巧&树状数组
点我看题 这题十分奇淫技巧...QAQ因为知道是树状数组的题QAQ刚开始以为维护两个数组的树状数组然后模拟从大到小,然后发现不会打QAQ 于是悄悄咪咪翻开题解了. 实际上两个数组可以看做一个数组 如 ...
- You only look once
计算MAP https://www.zhihu.com/question/53405779 http://tarangshah.com/blog/2018-01-27/what-is-map-unde ...
- Python学习札记(三) I/O
参考:输入和输出 I/O 1.print()函数 a.调用print()输出字符串有以下两种方式:(1)print('[字符串]') (2)print("[字符串]") b.调用p ...
- UVa 10883 超级平均数(二项式系数+对数计算)
https://vjudge.net/problem/UVA-10883 题意: 给出n个数,每相邻两个数求平均数,依次类推,最后得到1个数,求该数. 思路: 演算一下可以发现最后各个数的系数就是二项 ...
- 问下大家,chorme里用开发者工具看headers,点network标签然后刷新网页并没有headers选项,怎么破?
问下大家,chorme里用开发者工具看headers,点network标签然后刷新网页并没有headers选项,怎么破? 请教个问题 jmeter在Linux服务器压测,抛出很多错误率 但日志中没看到 ...
- spring的静态代理和动态代理
Java静态代理 Jdk动态代理 java代理模式 即Proxy Pattern,23种java常用设计模式之一.代理模式的定义:对其他对象提供一种代理以控制对这个对象的访问. 原理: 代理模式的主要 ...
- Spring Boot技术栈博客笔记(1)
要实现的核心功能 用户管理 安全设置 博客管理 评论管理 点赞管理 分类管理 标签管理 首页搜索 核心技术 数据存储 随着spring3发布以来,spring团队减少使用xml配置的使用,采用大量约定 ...