简单的类
定义一个简单的类,包含字段和方法:
class HelloWorld {
private var name = "Tomas"
def sayHello() { print("Hello, " + name) }
def getName = name
}
创建对象,并调用方法:
val helloWorld = new HelloWorld
helloWorld.sayHello()
print(helloWorld.getName)
注意:定义方法时如果没有参数,可以不加括号,也可以加括号;
定义的时候没加,在调用的时候就不要加,否则会报错;
如果在定义的时候有括号,那么在调用的时候也加上;
字段的get和set方法
在java中类字段设置值以及读取值,是通过 getter 和 setter 方法实现的;
Scala中也提供了getter和setter方法的实现,但是并没有定义成getXxx和setXxx;
class Counter {
var value = 0
def increment(step:Int) : Unit = { value += step }
def current(): Int = {value}
}
object MyCounter {
def main(args:Array[String]) {
val myCounter = new Counter
println(myCounter.value) // 不用getXxx获取字段的值
myCounter.value = 3 // 不用setXxx设置字段的值
myCounter.increment(1)
println(myCounter.current)
}
}
1、声明为 var 字段。编译器会自动定义为public域,并且提供public的getter和setter方法;
class Hello {
var name = "nicky"
def hello(password:String){
println("Welcome you to Scala World, " + name + ", you password is " + password)
}
def say {
println("Are u " + name + "?")
println("yes!!")
}
}
object Test {
def main(args:Array[String]):Unit = {
val hello = new Hello
println(hello.name)
hello.name = "Jack"
println(hello.name)
hello.say
}
}
2、声明为val字段。只会生成get方法,而不会生成set方法。因为 val 类型的变量,不能修改其值或者引用。
class Hello {
val name = "nicky"
def hello(password:String){
println("Welcome you to Scala World, " + name + ", you password is " + password)
}
def say {
println("Are u " + name + "?")
println("yes!!")
}
}
object Test {
def main(args:Array[String]):Unit = {
val hello = new Hello
println(hello.name)
hello.name = "Jack" // 不能通过编译
println(hello.name)
hello.say
}
}
3、声明为private var字段。此时默认生成的getter和setter方法也是private的,对其他类不可见。
class Hello {
private var name = "nicky"
def hello(password:String){
println("Welcome you to Scala World, " + name + ", you password is " + password)
}
def say {
println("Are u " + name + "?")
println("yes!!")
}
}
object Test {
def main(args:Array[String]):Unit = {
val hello = new Hello
println(hello.name) // 不能通过编译
hello.name = "Jack" // 不能通过编译
println(hello.name) // 不能通过编译
hello.say
}
}
4、将字段声明为private[this]。此时既不生成setter方法,也不会生成getter方法。
class Hello {
private[this] var name = "nicky"
def say {
println("Are u " + name + " ? ")
println("yes!!")
}
}
class Student{
// 对象私有字段。只能访问当前对象的privateAge字段
// 不能访问同样是Student类型的其他对象的该字段
private[this] var privateAge = 0
val name = "Scala"
val age = privateAge
// 编译错误,不能访问other对象的 privateAge 字段
def isYounger(other: Student) = privateAge < other.privateAge
}
5、自定义 get 和 set 方法。如果只是希望简单的get和set方法,按照scala提供的语法规则就可以了,根据需要为字段选择合适的修饰符,var、val、private、private[this]。
如果希望更好的控制get和set函数,可以自定义 getter 和 setter 方法。
class Student {
private var sname = "bell"
//自定义get方法
def name = "your name is " + sname
//自定义set方法。自定义set方法=号左边不能有空格,否则编译报错
def name_= (newValue: String) = {
sname = newValue
}
}
object Test{
def main(args: Array[String]):Unit = {
val s1 = new Student
s1.name_=("Jack1")
println(s1.name)
s1.name="Jack2"
println(s1.name)
}
}
6、如果不希望get和set方法暴露,但是希望其他类可以修改某一个字段的值,可以将字段定义成private,然后提供一个方法修改该字段
class Student {
private var sname = "bell"
//自定义get方法
def name = "your name is " + sname
def updateName(sname:String):Unit = {
this.sname = sname
}
}
object Test{
def main(args: Array[String]): Unit = {
val s1 = new Student
s1.updateName("jack")
println(s1.name)
}
}
7、如果不希望当前 private 字段被其他类的方法调用时访问,可以使用private[this]。
当前类Student,定义一个private字段 sname:
如果希望两个实例的name进行比较,private可以实现
如果希望不同实例间不能访问该字段,则需要使用private[this]
class Student{
private var sname = "bell"
def name = "name is "+sname
def name_=(newVal:String){
sname = newVal
}
def access(s:Student):Unit = {
sname.equals(s.sname)
}
}
class Student {
private[this] var sname = "bell"
def name = "name is "+sname
def name_=(newVal:String){
sname = newVal
}
def access(s:Student):Unit = {
sname.equals(s.sname) // 编译报错
}
}
8、生成java风格的 getter 和 setter 方法
import scala.beans.BeanProperty
class Student {
@BeanProperty
var name: String = _
@BeanProperty
var age: Int = _
}
object Test {
def main(args:Array[String]):Unit = {
val s = new Student
s.setName("Jack")
println(s.getName)
s.setAge(10)
println(s.getAge)
}
}
主构造器
Scala的每个类都有主构造器。但是,Scala的主构造器和Java有着明显的不同;
Scala的主构造器是整个类体,需要在类名称后面罗列出构造器所需的所有参数,这些参数被编译成字段,字段的值就是创建对象时传入的参数的值;
主构造器会执行类定义中的所有语句;
如果类名之后没有参数,则该类具备一个无参主构造器,这个构造器仅仅是执行类体中的所有语句。
class Counter(val name:String, val mode:Int) {
println("Primary consturctor starting ... ...")
private var value = 0
def increment(step:Int) : Unit = { value += step }
def current(): Int = {value}
def info:Unit = { printf("Name:%s and mode is %d \n", name, mode) }
}
object myCounter {
def main(args:Array[String]) {
val myCounter = new Counter("Timer", 2)
myCounter.info // 显示计数器信息
myCounter.increment(1) // 设置步长
printf("Current Value is :%d \n", myCounter.current) // 显示计数器当前值
}
}
Scala构造器包含1个主构造器和若干个(0个或多个)辅助构造器
辅助构造器的名称为this,每个辅助构造器都必须调用一个此前已经定义的辅助构造器或主构造器
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
}
def description = name + " is " + age + " years old"
}
val p1 = new Person // 调用主构造器
val p2 = new Person("Fred") // 调用第一个辅助构造器
val p3 = new Person("Fred", 42) // 调用第二个辅助构造器
p1.description
p2.description
p3.description