5.1 简单类和无参方法
Class Counter {
private var value = 0 // 必须初始化字段
def increment() { value += 1 } // 方法默认是公有的
改值器
def current() = value //
取值器
// def current = value
}
val myCounter = new Counter // 或 new Counter
()
mycounter.increment()
println(myCounter.current)
调用无参方法(比如current) 时,你可以写上圆括号,也可以不写。为对于改值器方法(即改变对象状态的方法)使用0,而对于取位器方法(不会改变对象状态的方法)去掉()是不错的风柏。
class Person {
var age = 0
}
Scala生成面向JVM的类,其中有一个私有的age字段以及相应的getter和setter方法。这两个方法是公有的.因为我们没有将age声明为private;(对私有字段而言,getter和setter方法也是私有的。)
在Scala中,
getter和setter分别叫做
age 和
age_=。
可以编译Person,然后用javap -private 查看字节码文件:
$ scalac Person.scala
$ javap - private Person
class Person {
private var privateAge = 0 //变成私有并改名
// 向己重新定义getter和setter方法
def age = privateAge
def age_ = (newValue: Int) { if (newValue > privateAge) privateAge = newValue}
}
如果字段是私有的,则getter和setter方法也是私有的。
如果字段是val, 则只有getter方法被生成。
如果你不需要任何getter或setter , 可以将字段声明为private[this],即对象私有。
访问权限:
方法可以访问该类的所有对象的私有字段;
若Counter类中value字段声明为private[this],则Counter类的方法只能访问到当前对象的value字段,而不能访问同样是Counter类型的其他对象的该字段
5.5 Bean属性
当将Scala字段标注为@BeanProperty时,getter,setter方法会自动生成.
import scala. reflect.BeanProperty
class Person {
@BeanProperty var name: String = _
}
将会生产四个方法:
- name: String
- name_=(newValue: String): Unit
- getName(): String
- setName(newValue: String): Unit
5.6 辅助构造器(auxiliary constructor)
同Java或c++的构造器十分相似,只有两处不同。
1.辅助构造器的名称为this() (在Java或c++中,构造器的名称和类名相同--当你修改类名时就不那么方便了。)
2. 每一个辅助构造器都必须以一个对先前已定义的其他辅助构造器或主构造器的调用开始。
这里有一个带有两个辅助构造器的类。
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
}
}
你可以以三种方式构建对象:
val pl = new Person // 主构逸待
val p2 = new Person( "Fred") // 第一个辅助构造得
val p3 = new Person ("Fred" , 42) // 第二个辅助构造器
5.7 主构造器
在Scala中,每个类都有主构造器。主构造器并不以this方法定义,而是与类定义交织在一起。
1. 主构造器的参数直接放置在类名之后。
class Person(val name: String, val age: Int) {
// (... )中的内容就是主构造器的参数
...
}
2. 主构造器会执行类定义中的所有语句。例如在以下类中:
class Person(val name: String, val age: Int) {
pringln("Just construnted another person")
def description = name + " is " + age + " years old."
...
}
如果类名之后没有参数,则该类类具备一个无参主构造器。这样一个构造器仅仅是简单地执行类体中的所有语句而已。
5.8 嵌套类
可以在函数中定义函数,在类中定义类。
和Java不同, 在Java中内部类从属于外部类。Scala采用的方式更符合常规。举例来说,要构建一个新的内部对象, 你只需要简单的new这个类各new chatter.Member。而在Java中,你需要使用一个特殊语法: chatter.new MemberO 。
import scala.collection.mutable.ArrayBuffer
class NetWork{
class Member(val name:String){
val contacts = new ArrayBuffer[Member]
}
private val members = new ArrayBuffer[Member]
def join(name:String) ={
val m=new Member(name)
members+=m
m
}
}
每个网络实例都 有它自已的Member类,如,下例是两个网络:
val chatter = new Network
val myFace = new Network
chatter.Member和myFace.Member是不同的类。
不能将其中一个网络的成员添加到另一个网络。如果不想有这个约束,则应该 把Member类直接挪到Network类之外。一个好的地方可能是Network的伴生对象。如果你要的是细粒度的类,只是偶尔想使用更为松散的定义,那么可以用”类型投影”Network#Member,意思是任何Network的Member。
class Network{
class Member(val name:String){
val contacts = new ArrayBuffer[network#Member]
}
}