作为Java开发人员,我们习惯于JavaBean风格的domain classes,它们不仅包含带有getters和setters的域,还有构造器以及hashCode、equals、toString方法。
在Scala中实现上面所说的很简单,只需要在类声明前加上case。例如:
scala> case class Money(amount:Int=1, currency:String="USD")
这样,我们就定义了一个Money类,它有2个immutable fields。
此时Money类不仅仅拥有了传统的JavaBean风格的domain class所拥有的特性,还有了模式匹配的强大机制。case类似于Java中的switch语句,但是它更灵活,后面我们会看到。case classes还有其他的特性,其中之一就是工厂方法用于创建对象(无需用new关键字来创建对象)。
默认,Scala类中声明的字段是public的,当然我们也可以写成private,还可以用var声明为mutable字段。
例如:case class Money(private val amount:Int, private var currency:String)
用最简短的方式创建Money的一个实例很简单:
scala> val defaultAmount = Money()
defaultAmount: Money = Money(1, USD)
scala> val fifteenDollars = Money(15, "USD")
fifteenDollars: Money = Money(15, USD)
scala> val fifteenDollars = Money(15)
fifteenDollars: Money = Money(15, USD)
但是,像下面这样调用就是错的,当你只提供第2个参数的时候:
scala> val someEuros = Money("EUR")
所以,我们应该显式指出字段名,例如:
scala> val someEuros = Money(currency = "EUR")
构造实例时,还有个有用的方法就是copy方法,它会从原实例创建一个新实例,并利用给定的参数替换掉一些值:
scala> val tenEuros = twentyEuros.copy(10)
tenEuros: Money = Money(10, EUR)
当然也可以像前面那样,显式指定字段名,如:
scala> val twentyDollars = twentyEuros.copy(currency="USD")
在Scala中,我们用def关键字来定义一个class method或一个function。例如:
scala> case class Money(val amount:Int=1, val currency:String="USD") {
def +(other: Money) : Money = Money(amount + other.amount)
}
注意,我们用+作为方法名,还在方法签名的声明中加入了返回类型(是可选的,因为Scala的类型推断会算出类型,但显式写出来对于public methods来说是一个好的文档实践,方法如果没有指明其他scope,那默认就是public的)
还有,就是Scala中,方法最后面的return word是可选的,最后一条语句总是作为返回值返回给它的调用者。通常建议省略掉return。
现在,我们就可以将2个Money实例加起来了,例如:
scala> Money(12) + Money(34)
res5: Money = Money(46, USD)
一旦,我们开始操作对象的集合时,事情就开始变得有趣了,Scala的functional编程对此帮助很大。
scala> val numbers = List(1,2,5)
numbers : List[Int] = List(1,2,5)
Scala collections有组织地将immutable collections和mutable collections区分开,通过默认构造的是immutable collections来鼓励immutability。也就是当additions,updates,removals操作后返回的是新集合。
scala> for (n <- numbers) println("Number " + n)
还有种写法就是更functional style,就是使用lambda表达式,有时叫作闭包,简短来说,lambda就是函数,你可以将其作为参数传递。这些函数带有输入参数,并返回方法体中的最后一条语句或行)。格式为:
functionName { input => body }
具体的例子就是:
scala> numbers.foreach { n:Int => println("Number " + n) }
上面的代码中,方法体中只有一条语句,也就是println...,因此返回Unit,大致类似于Java中的void,但void并不返回任何东西。
前面,我们说过,Scala collections默认是immutable的,这保证了在处理多处理器架构时行为的正确性。Scala的集合和Java的集合相比,它支持并行操作。