类在 Scala 中是创建对象的蓝图。类可以包含方法,常量,变量,类型,对象,特征和类,它们被统一称为成员。类型成员,对象成员和特征成员将在之后讨论。
定义一个类 (Defining a class)
一个最小的类定义是一个类关键字 class
和一个类名。类名应该首字母大写。
class User
val user1 = new User
关键字 new
用来创建一个类的实例。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
。不像其它的语言,Scala 中主构造器是在类名之后 (var x: Int, var y: Int)
。move
方法有两个整型参数且返回值为 Unit
类型的 ()
,就是没有返回值。这一点大致对应 类 Java 语言 中的 void
类型。toString
方法没有参数且返回一个 String
类型的值。而且 toString
方法是重写了 AnyRef
类的 toString
方法。所以使用 override
关键字进行标记。
构造器 (Constructors)
构造器的参数是可选的当参数提供了一个默认值就像下面时:
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 Members and Getter/Setter Syntax)
类的成员默认都是公有的。不过,使用关键字 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
在这个 Point
类中,数据被存储在私有的成员变量 _x
和 _y
中。这两个方法def x
和 def y
被用来访问私有的数据。 而方法 def x_=
和 def _=
被用来验证和设置 _x
和 _y
的值。注意 Setter 的特殊语法:在 getter 的方法名后加 _=
然后接参数。
使用关键字 var
和 val
修饰的构造器参数都是公有成员。但是,因为被 val
修饰的参数是不可变的,所以,你不能更改它。
class Point(val x: Int, val y: Int)
val point = new Point(1, 2)
point.x = 3 // <-- 不能通过编译
没有关键字 var
和 val
修饰的构造器参数是私有成员,仅在类中是可见的。
class Point(x: Int, y: Int)
val point = new Point(1, 2)
point.x // <-- 不能通过编译
网友评论