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 或试图修改是不成功的。
