Scala 中的类是创建对象的蓝图。类中可以包含方法,值,变量,类型,对象,traits(特征)和成员类。类型,对象和traits(特征)将在后面介绍。
定义类
最简单的类定义就是使用关键字 class
和标识符。类名应该使用大写。
class User
val user = new User
使用关键字 new
去创建一个类的实例对象。因为User
没有自定义的构造器,所以Scala会为User提供一个默认的无参构造器。但是,我们更多的会去创建构造器和类体。接下来定义一个 Point
示例类:
class Point(var x: Int, var y: Int) {
def move(dx: Int, dy: Int): Unit = {
x = x + dx
y = y + dy
}
override def toString: String =
s"($x, $y)"
}
val point1 = new Point(2, 3)
point1.x // 2
println(point1) // prints (2, 3)
Point
类有四个成员:变量 x
和 y
,方法 move
和 toString
。不像许多其他语言一样,主构造器(var x: Int, var y: Int)
定义在类的签名中,move
方法含有两个整型参数并返回不带任何信息的Unit
值()
。Unit
和Java语言中的void
类似。另一方面,String
方法没有参数仅仅返回一个字符串的值,因为 toString
使用 override
关键字重写了 AnyRef
中的 toString
方法。
构造器
通过提供默认值,构造方法可以具有可选参数。如下所示:
class Point(var x: Int = 0, var y: Int = 0)
val origin = new Point // x and y are both set to 0
val point1 = new Point(1)
println(point1.x) // prints 1
在 Point
类中,因为 x
和 y
都有默认值0,所以就不需要参数了。但是,因为构造器是从左到右读取参数的,所以如果你只想传一个 y
值的话,那就需要给这个参数命名。
class Point(var x: Int = 0, var y: Int = 0)
val point2 = new Point(y=2)
println(point2.y) // prints 2
这也是明确指定值的良好做法。
私有成员和Getter/Setter语法
成员默认都是公开的的,使用 private
访问修饰符对外部类隐藏实现细节。
class Point {
private var _x = 0
private var _y = 0
private val bound = 100
def x = _x
def x_= (newValue: Int): Unit = {
if (newValue < bound) _x = newValue else printWarning
}
def y = _y
def y_= (newValue: Int): Unit = {
if (newValue < bound) _y = newValue else printWarning
}
private def printWarning = println("WARNING: Out of bounds")
}
val point1 = new Point
point1.x = 99
point1.y = 101 // prints the warning
在Ponit
类中,数据存储在私有变量 x
和 y
中。方法 def x
和 def y
用于访问私有数据。方法 def x_=
和 def y_=
用于校验和设置变量 _x
和 _y
的值。注意用于setters的特殊语法:该方法把 _=
附加到 getter 标识符上并且后面跟着参数。
主构造器中使用 var
或 val
声明的参数都是公开(public
)的。但是,因为 val
是不可变的,所以不能随意修改。看下面例子:
class Point(val x: Int, val y: Int)
val point = new Point(1, 2)
point.x = 3 // <-- does not compile
上面的程序试图去修改 val
声明的 x
参数是不成功的。
没有使用 val
或 var
声明的参数是私有值,仅仅对于类的内部可见。
class Point(x: Int, y: Int)
val point = new Point(1, 2)
point.x // <-- does not compile
想直接访问私有属性 x
或试图修改是不成功的。