为了支持面向对象编程,Scala提供了一个类构造。它的语法比Jaca,C#更简洁,但依然很容易使用和阅读。
基本类构造器
下面是个Scala类,它的构造器定义了两个参数:firstName 和lastName:
class Person(var firstName: String, var lastName: String)
根据这一定义,你可以这个创建 Person 实例:
val p = new Person("Bill", "Panner")
在类构造器中定义的参数会自动地创造类中的字段,你可以像下面这样访问这些字符:
println(p.firstName + " " + p.lastName)
Bill Panner
在这个例子中,因为两个字段都定义为 var 类型的,意味着它们是可以被修改的:
scala> p.firstName = "William"
p.firstName: String = William
scala> p.lastName = "Bernheim"
p.lastName: String = Bernheim
如果你是从Java来的,这个Scala代码:
class Person(var firstName: String, var lastName: String)
大致与下面的Java代相等:
public class Person {
private String firstName;
private String lastName;
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return this.lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
val 使字段为只读
你可以定义它们为 val , 这样它们就是不可变的:
class Person(val firstName: String, val lastName: String)
--- ---
如果你现在再去改变,会报错:
scala> p.firstName = "Fred"
<console>:12: error: reassignment to val
p.firstName = "Fred"
^
scala> p.lastName = "Jones"
<console>:12: error: reassignment to val
p.lastName = "Jones"
^
当你用scala写OOP代码,创建字段时使用 var ,这样你可以改变它。
当你用scala写FP代码时,你一般会用 case class 来替代像上面例子中的类。
类构造器
在scala中,类的主构造器是下面的组合:
- 构造器参数
- 类体中调用的方法
- 类体中执行的语句和表达式
在类主体中声明的字段以类似Java中的形式处理:它们是类第一次实例化时分配的。
下面的 Person类,展示了你可以在类体中做的很多事:
class Person(var firstName: String, var lastName: String) {
println("the constructor begins")
// 'public' access by default
var age = 0
// some class fields
private val HOME = System.getProperty("user.home")
// some methods
override def toString(): String = s"$firstName $lastName is $age years old"
def printHome(): Unit = println(s"HOME = $HOME")
def printFullName(): Unit = println(this)
printHome()
printFullName()
println("you've reached the end of the constructor")
}
在REPL中:
scala> val p = new Person("Kim", "Carnes")
the constructor begins
HOME = /Users/al
Kim Carnes is 0 years old
you've reached the end of the constructor
p: Person = Kim Carnes is 0 years old
scala> p.age
res0: Int = 0
scala> p.age = 36
p.age: Int = 36
scala> p
res1: Person = Kim Carnes is 36 years old
scala> p.printHome
HOME = /Users/al
scala> p.printFullName
Kim Carnes is 36 years old
当你从一个更加冗长的语言转到scala,一开始会对这个构造器方法感到一些不适应,但是一旦你理解了,并用它写了几个类,你会发现它是符合逻辑的又很方便。
一些其他的示例
class Pizza (var crustSize: Int, var crustType: String)
// a stock, like AAPL or GOOG
class Stock(var symbol: String, var price: BigDecimal)
// a network socket
class Socket(val timeout: Int, val linger: Int) {
override def toString = s"timeout: $timeout, linger: $linger"
}
class Address (
var street1: String,
var street2: String,
var city: String,
var state: String
)