scala - 面向对象编程
定义类来说不需要修饰,直接使用 class 创建即可。
代码语言:javascript复制class HelloWorld{
private var name = "Li"
def sayHello(){
print("Hello," " " name)
}
// 不加括号的方法调用时也不能加
def getName = name
}
// 创建对象
val helloWorld = new HelloWorld
helloWorld.getName
getter 与 setter
定义不带 private 的 var field,此时 scala 生成的面向 JVM 的类时,会定义为 private 的 name 字段,并提供 public 的 getter 和 setter 方法。
如果使用 private 修饰 field ,则生成的 getter 和 setter 也是 private 的。
如果定义 val field ,则只会生成 getter 方法。
如果不希望生成 setter 和 getter 方法, 则将 field 声明为 private[this] 。
调用 getter 和 setter 方法,分别叫做 name 和 name = 。
自己定义 getter 与 setter
代码语言:javascript复制class Student{
private var myName = "Li"
def name = "your name is" myName
def name_=(newValue:String){
println("you cannot edit your name!")
}
}
如果不希望 field 有 setter 方法,则可以定义为 val ,但是此时就不能更改 field 的值了。
如果希望能够仅仅暴露出一个 getter 方法,并且还能通过某些方法更改 field 的值,那么需要综合使用 private 以及自定义 getter 方法。此时由于 field 是 private 的,所以 setter 和 getter 都是 private ,对外界没有暴露;自己可以实现修改 field 值的方法;自己可以覆盖 getter 方法。
代码语言:javascript复制class Student {
private var myAge = 0
def age_=(newAge: Int){
if(newAge > 0) myAge = newAge
else println("illegal age!")
}
def age = myAge
def older(s: Student) = {
myAge > s.myAge
}
}
对比:
代码语言:javascript复制class Student{
private[this] var myAge = 0
def age_=(newAge:Int){
if(newAge > 0 ) myAge = newAge
else println("illegal age!")
}
def age = myAge
def older(s:Student) = {
myAge > s.myAge
}
}
//在这里就不能正常定义,因为访问不到 older 方法中的 myAge 。
如果将 field 使用 private 来修饰,那么代表这个 field 是类私有的,在类的方法中,可以直接访问类的其他对象的 private field 。
如果不希望 field 被其他对象访问到,那么可以使用 private[ this ] ,意味着对象私有的 field ,只有本对象内才可以访问到。
Java 风格的 getter 和 setter 方法
Scala 的 getter 和 setter 方法的命名和 Java 是不同的,是 field 和 field_= 的方式。
如果要让 Scala 自动生成 Java 风格的 getter 和 setter 方法,在 field 添加 @BeanProperty 注解即可。
辅助 constructor
在 Scala 中,可以结合类定义多个辅助 constructor ,类似 Java 中的构造函数重载。
辅助 constructor 之间可以互相调用,而且必须第一行调用主 constructor 。
代码语言:javascript复制class Student{
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
}
}
主 constructor
在 Scala 中,主 constructor 是与类名放在一起的,与 Java 不同。
在类中,没有定义在任何方法或者是代码之中的代码,就是主 constructor 的代码。
代码语言:javascript复制class Student(val name:String, val age:Int){
println("your name is " name ", your age is " age)
}
// 主 contructor 中还可以通过使用默认参数,来给参数默认的值。
class Student(val name:String = "Li", val age:Int = 30){
println("your name is" name ", your age is " age )
}
如果主 constructor 传入的参数什么修饰都没有,比如 name:String ,那么如果类内部的方法使用到了,则会声明为 private[this] name ;否则没有该 field, 就只能是被 constructor 代码使用而已,这是一种优化机制。
内部类
在 Scala 中,同样的可以在类中定义内部类,但是与 Java 不同的是,每个外部类的对象的内部类都是不同的类。
意思就是定义之后生成两个外部类,那么这两个外部类的内部类不是同一种。