Scala--对象

  Scala对象,在scala中没有静态方法或静态字段,我们可以用object,这个语法结构来达到目的。对象,定义了某个类的单个实例。

单例对象

使用object中的常量或方法,通过object名直接调用,对象构造器在对象第一次被使用时调用如果某对象一直未被使用,那么其构造器也不会被调用)。object的构造器不接受参数传递

  • 一个简单的例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 单例对象
* Created by xiaoxiaomo on 2016/3/29.
*/

object Compute {
//在对象中定义变量
//即静态的常量可以直接使用Compute.sums调用
var sums = 0

def sum( a : Int , b :Int ) : Int = {
sums = a + b //不需要添加return
sums
}
}

object isSame{
//test
def main (args: Array[String]){
println( Compute.sum(8,9) )//静态方法
println( Compute.sums )//静态常量
//判断是否是相同对象
println(Compute == Compute)//true
}
}
  • 运行结果
1
2
3
17
17
true

可以看出object定义的方法和变量,就类是于java中的静态方法和变量。
获取属性:object对象名.属性,eg:Compute.sums ;
获取方法:object对象名.方法名(参数列表),eg:Compute.sum(8,9) ;

伴生对象

在上面我们可以创建静态方法和静态字段,但如果我们要想使用静态类呢?或在静态类中定义静态常量怎么办?解决办法就是定义一个和类相同名称的object对象,这个对象叫做“伴生对象”。我们可以把方法和字段定义到伴生对象当中,已达到类似的静态类和静态常量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
* 伴生对象
* Created by xiaoxiaomo on 2016/3/29.
*/

class Account {

//调用伴生对象,即使是私有的
//必须使用:伴生对象.方法
var id = Account.newUniqueNuber()

private var balance = 0.0

def deposit(amount:Double): Unit ={
balance += amount
}

//这个不是伴生对象,newUniqueNumber为private
//然后这里调用就会失败,
//Accounts.newUniqueNuberPri() ;
}

//伴生对象
object Account{

private var lastNumber = 0 ;

//在该Account作用范围之外无法调用
private def newUniqueNuberPri() = {
lastNumber += 1
lastNumber
}

def newUniqueNuber() = {
lastNumber += 1
lastNumber
}
}

伴生对象与类同名,且必须放置在同一源文件中。
类可以访问伴生对象私有特性,但是必须通过 伴生对象.属性名伴生对象.方法调用。
类和它的伴生对象可以互相访问私有特性

继承或扩展多个特质

对象可以扩展一个类,并继承,就是面向对象的特征之一,即:如果子类继承了父类,子类就拥有了父类所有共有的特性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
* 继承
* Created by xiaoxiaomo on 2016/3/29.
*/

abstract class Person(var name:String = "momo", var age:Int){
var height = 178
private val sex = 0
def info():Unit

def info2(){
println("name:"+name+", sex:"+sex)
}
}

object man extends Person("xiaoxiaomo", 23){
//实现方法
def info(){
println("my name:"+name+", age:"+age +","+height)
}
}

object woman extends Person("",22){
//实现方法
def info(){
println("my name:"+name+",age:"+age /*, + sex*/)
}
}

object test{
def main(args: Array[String]) {
man.info()
man.info2()
woman.info()
}
}
  • 运行结果
1
2
3
my name:xiaoxiaomo, age:23,178
name:xiaoxiaomo, sex:0
my name:,age:22

子类继承父类,就拥有了父类所有非私有特性,eg:上例中height,name…,info2()
必须实现“抽象”(def 方法名([参数列表]):Unit)方法,普通方法可以不实现,eg必须实现info(),可以不重写info2()

apply方法

其实我们平常都在使用apply方法,当遇到如下表达式的时候,apply方法便会被调用:

object(参数1, 参数2,….,参数N)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* apply方法
* Created by xiaoxiaomo on 2016/3/29.
*/

class AccountApply ( val id : Int , initialBalance : Double ) {

//
private var balance = initialBalance ;

}

//伴生对象
object AccountApply{

//apply方法
def apply( initialBalance : Double ) =
new AccountApply(Compute.sum(8,9) ,initialBalance) ;

def main(args: Array[String]) {

val acct = AccountApply(1000.0) ;
println(acct)
}
}

main方法

main方法定义在object中,形式如下:

1
2
3
4
5
object HelloWorld{
def main(args: Array[String]){
println("Hello World!")
}
}

还有一种方式:通过继承App,然后将程序代码放object体内就可

1
2
3
object HelloWorld extends App{
println("Hello World!")
}

枚举

Scala并没有定义枚举类型,但是可以通过定义扩展Enumeration的对象,并用Value方法初始化枚举类中的所有可选值,提供枚举。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/**
* 枚举
* Created by xiaoxiaomo on 2016/3/29.
*/

object Week extends Enumeration{
//第一种初始化
var Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday = Value

//第二种初始化
val M = Value
val T = Value
val W = Value

//第三种初始化
//调用Value方法设置值id或者name
//id为Int,name为String
val M2 = Value(30,"M2")
val M3 = Value(40)//可以只设置id或name
val M4 = Value("M4name")//Id默认为11,在之前+1

}

object testEnume{

def main(args: Array[String]) {
val Mon = Week.Monday
val M4Id = Week.withName("M4name") //获取Id
val m4 = Week(41) //获取值

//遍历
for ( w <- Week.values ){
printf("id:%s , value:%s",w.id,w)
println ("")
}


println("Mon:"+Mon)
println("M4Id:"+M4Id)
println("m4:"+m4)
}
}
  • 运行结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
id:0 , value:Monday
id:1 , value:Tuesday
id:2 , value:Wednesday
id:3 , value:Thursday
id:4 , value:Friday
id:5 , value:Saturday
id:6 , value:Sunday
id:7 , value:M
id:8 , value:T
id:9 , value:W
id:30 , value:M2
id:40 , value:M3
id:41 , value:M4name
Mon:Monday
M4Id:M4name
m4:M4name

对于枚举的初始化,有上例中的三种方法;
第三种初始化可以指定id或者name,id为Int类型,name为String类型
可以通过id获取值(eg:Week(41)默认调用了apply方法),也可以通过值来获取id(withName方法)。

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器