scala - 面向对象编程

定义类来说不需要修饰,直接使用 class 创建即可。

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
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 方法。

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
}
}

对比:

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 。

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 的代码。

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 不同的是,每个外部类的对象的内部类都是不同的类。

意思就是定义之后生成两个外部类,那么这两个外部类的内部类不是同一种。