一、类定义
(1)定义类,包含field以及方法
class ScalaClass {private var field = "one"def aMethod() { print("field : " + field ) } def getField = field }
(2)调用对象方法
val scalaClass = new ScalaClassscalaClass.aMethod()
print(scalaClass.getField) // 也可以不加括号,如果定义方法时不带括号,则调用方法时也不能带括号
(3)getter与setter
1)var
此时scala生成的面向JVM的类时,会定义为private的name字段,并提供public的getter和setter方法。如:var field
2)val
只会生成getter方法。如:val field
3)private
生成的getter和setter也是private的,与java的私有属性变量类内访问一致。如:private var field
4)private[this]
不生成setter和getter方法,并且只是当前对象能够访问,与java的私有属性变量类内访问不一致。如:private[this] var field
5)自定义getter与setter方法
定义setter方法,def field_=(val: type){ },自定义setter方法的时候注意scala的语法限制,签名、=、参数间不能有空格
定义getter方法,def field=xxx
class Person{private var lastName = "mk"def name = lastName def name_=(newVal: String) {lastName=newVal}}val mk = new Personprint(mk.name)mk.name = "xx"// 调用getter和setter方法,分别叫做name和name_ =
6)Java风格的getter和setter方法
Scala的getter和setter方法的命名与java是不同的,是field和field_=的方式
让scala自动生成java风格的getter和setter方法,只要给field添加@BeanProperty注解即可
此时会生成4个方法,name: String、name_=(newValue: String): Unit、getName(): String、setName(newValue: String): Unit
import scala.reflect.BeanPropertyclass Person{@BeanProperty var name: String = _}class Person(@BeanProperty var name: String)val s = new Persons.setName("MK")s.getName()
7)辅助constructor
Scala中,可以给类定义多个辅助constructor,类似于java中的构造函数重载
辅助constructor之间可以互相调用,而且必须第一行调用主constructor
class Person {private var name = ""private var age = 0def this(name: String) {this()this.name = name}def this(name: String, age: Int) {this(name)this.age = age}
}
8)主constructor
Scala中,主constructor是与类名放在一起的,与java不同
而且类中没有定义在任何方法或者是代码块之中的代码,就是主constructor的代码,没有java构造方法清晰
class Person(val name: String, val age: Int) {println("name:" + name + ", age:" + age)}
主constructor中还可以通过使用默认参数,来给参数默认的值
class Person(val name: String = "MK", val age: Int = 18) {println("name:" + name + ", age:" + age)}
主constrcutor传入的参数什么修饰都没有,比如name: String,那么如果类内部的方法使用到了,则会声明为private[this] name;否则没有该field,就只能被constructor代码使用
二、对象object
object,相当于class的单个实例,在里面定义一些静态的field或者method(等价于java的定义静态变量和静态方法的类)
第一次调用object的方法时,就会执行object的constructor(即object内部不在method中的代码)。object不能定义接受参数的constructor
object通常用于作为单例模式的实现,或者放class的静态成员,比如工具方法
object Num {private val zero = 0println("init Number object!")def getZero = zero}
(1) 伴生对象
有一个class,还有一个与class同名的object,那么就称这个object是class的伴生对象,class是object的伴生类
伴生类和伴生对象必须存放在一个.scala文件之中
伴生类和伴生对象,最大的特点就在于,互相可以访问private field
object Num {private val zero = 0println("init Number object!")def getZero = zero}class Num (val valueNum: Int) {def getValue = valueNum
}
(2)object继承抽象类
object的功能其实和class类似,除了不能定义接受参数的constructor之外,object也可以继承抽象类,并覆盖抽象类中的方法
abstract class Animal(var name: String) {def toStr(): String
}object Cat extends Animal("cat") {override def toStr() = name
}
(3) apply方法
apply方法通常在伴生对象objec中实现apply方法实现构造伴生类的对象的功能。
而创建伴生类的对象时,一般不会使用new ClassName的方式,而是使用ClassName()的方式,隐式地调用伴生对象得apply方法,这样会让对象创建更加简洁
比如,Array类的伴生对象的apply方法就实现了接收可变数量的参数,并创建一个Array对象的功能
var arr = Array("a", "b")
class Cat(val name: String)
object Cat{def apply(name: String) = new Cat(name)
}
(4) main方法
在scala中要运行一个应用程序,那么必须有一个main方法,作为入口(像java中需要编写一个包含main方法类)
scala中的main方法必须在object中定义,格式为def main(args: Array[String])
object ScalaProgram {def main(args: Array[String]) {println("scala run...")}}
除了实现main方法可以作为启动入口,继承App Trait类也可以作为启动入口,然后将需要在main方法中运行的代码,直接作为object的constructor代码;而且用args可以接受传入的参数
object ScalaProgram extends App {println("scala run ...")}
运行上面的代码,需要将其放入ScalaProgram.scala文件,然后先使用scalac编译,再用scala执行
scalac ScalaProgram.scala
scala -Dscala.time ScalaProgram
App Trait的工作原理:App Trait继承自DelayedInit Trait,scalac命令进行编译时,会把继承App Trait的object的constructor代码都放到DelayedInit Trait的delayedInit方法中执行。
(5)object实现枚举
Scala没有直接提供类似于Java中的Enum类的枚举特性,如果要实现枚举,则需要用object继承Enumeration类,并且调用Value方法来初始化枚举值
通过Value传入枚举值的id和name,通过id和toString可以获取; 还可以通过id和name来查找枚举值。使用枚举object.values可以遍历枚举值
object Sex extends Enumeration {val MAN = Value(0, "man")val WOMAN = Value(1, "woman")}Sex(0)
Sex.withName("man")
for (s <- Sex.values) println(s)