简单类和无参方法

Scala类最简单的形式和Java相似:

1
2
3
4
class Counter {
private var value = 0 //必须初始化
def increment() { value += 1} //方法默认是公有的
def current () = value

在scala中,类并不声明为public,scala源文件可以包含多个类,所有这些类都具有公有可见性。

调用无参方法时,可以使用圆括号,也可以不使用。一般的,对于改值器方法使用(),对于取值器方法则去掉()。

也可以使用不带()的方式声明current来强制调用的时候不使用()。

带有getter和setter的属性

Scala对每一个字段都提供了getter和setter方法。这里定义一个公有字段:

1
2
3
class Person {
var age = 0
}

Scala生成面向JVM的类,其中有一个私有的age字段以及相应的getter和setter方法。这两个方法是公有的,因为我们没有将age声明为private。对于私有字段而言,getter和setter也是私有的。

在scala中,getter和setter分别叫做age和age_=。
例如:

1
2
println(fred.age)
fred.age = 20

在任何时候你都可以自己重新定义getter和setter方法。

如果字段是val,则只有getter方法被生成。如果你不需要任何getter和setter,可以将字段声明为private[this]。

###只带getter的属性

是用val字段,scala会生成一个final字段和一个getter方法。

对象私有字段

在scala中,方法可以访问该类的所有对象的私有字段。scala允许我们定义更加严格的访问限制,通过private[this]这个修饰符实现。

1
private[this] val value = 0 //类似某个对象.value这样的访问将不被允许

这样的访问有时候称之为对象私有的。

对于类私有的字段,scala会生成私有的getter和setter方法,但对于对象私有的字段,scala根本不会生成getter和setter方法。

scala允许将访问权赋予给指定的类,private[类名]修饰符可以定义仅有指定类的方法可以访问给定的字段。这里的类必须是当前定义的类,或者是包含该类的外部类。

辅助构造器

和Java一样,Scala也可以有任意多的构造器,包括主构造器与辅助构造器。

辅助构造器与Java的构造器类似,只有两处不同:

  • 辅助构造器的名称为this
  • 每一个辅助构造器都必须以一个对先前已定义的的其他辅助构造器或主构造器的调用开始。

下面的类中包含两个辅助构造器:

1
2
3
4
5
6
7
8
9
10
11
12
class Person{
private var name = ""
private var age = 0
def this(name:String) {
this()
this.name = name
}
def this(name:String, age:Int){
this(name)
this.age = age
}
}

一个类如果没有显示定义主构造器则自动拥有一个无参的主构造器。
现在,我们可以使用三种方式构建对象:

1
2
3
val p1 = Person
val p2 = Person("Jim")
val p3 = Person("Jim",12

主构造器

在scala中,每个类都有主构造器,主构造器并不以this方法定义,而与类定义交织在一起。

  1. 主构造器的参数直接放置在类名之后。
1
2
3
class Person(val name:String, val age:Int){
...
}

主构造器的参数被编译成字段,其值被初始化成构造时传入的参数。

  1. 主构造器会执行类定义中的所有字段。例如:
1
2
3
4
class Person(val name:String, val age:Int){
println("Just constructed another person")
...
}

println语句是主构造器的一部分,每当有对象被构造出来的时候,上述代码就会被执行。当你I需要再构造过程中配置某个字段的时候这个特性特别有用。

如果类名之后没有参数,则该类具备一个无参主构造器,这样的一个构造器仅仅简单的执行类体中的所有语句而已。

构造函数也可以是普通的方法参数,不带val或var。这样的参数如何处理取决于它在类中如何被使用。

  • 如果不带val或者var参数至少被一个方法所使用,它将被升格为字段。例如:
    1
    2
    3
    class Person(name:String, age:Int){
    def description = name + " is " + age + " years old"
    }

上述代码声明并初始化了不可变字段的name和age。而这两个字段都是对象私有化的。类似这样的字段等同于private[this] val字段的效果。

  • 否则,该参数将不被保存为字段,它仅仅是一个可以被主构造器中的代码访问的普通参数表。

如果想让主构造器变成私有的,可以像这样放置private关键字。

1
2
3
class Person private (val id:Int){
...
}

这样一来,用户就必须通过辅助构造器来构造Person对象了。

嵌套类

在scala中,你几乎可以在任何语法结构中内嵌任何语法结构,你可以在函数中定义函数,也可以在类中定义类。