essential scala: 伴生对象

essential scala: 伴生对象

有时候我们想创建属于类的方法,在java中使用static关键字. 在scala中使用单例对象实现. class中的方法可以看作是static的,对象中的方法则可以看作是对象所独有的方法.

一种常见应用就是实现多个构造函数. 虽然scala在语法上完全可以给一个class添加多个构造函数,但是scala程序员比较倾向于写一个同名单例对象,在这个单例中实现apply方法. 往往把这个同名对象叫做这个class的伴生对象(companion object).

class Timestamp(val seconds: Long)
object Timestamp {
    def apply(hours: Int, minutes: Int, seconds: Int): Timestamp =
        new Timestamp(hours*60*60 + minutes*60 + seconds)
}
Timestamp(1, 1, 1).seconds
// res: Long = 3661

在scala终端中定义伴生对象

键入 :paste 进入粘贴模式. 因为伴生对象必须和其对应的class同时编译,意味着他们必须被定义在一个文件中,在交互式终端中要使用:paste. 使用:help获取更多帮助.

scala> :paste
// Entering paste mode (ctrl-D to finish)

重点说明的一点是,伴生对象并不是一个类的实例,而是一个拥有自己类型的单例对象.

Timestamp // note that the type is `Timestamp.type`, not `Timestamp`
// res: Timestamp.type = Timestamp$@602b24e6

语法

在同一个文件中,同名.

class Name {
...
}
object Name {
...
}

总结

伴生对象与对应的类紧密关联,但是不必创建任何类的实例,常用于额外的构造函数.

伴生对象替代了java的static方法,同样的功能同时更加灵活.

伴生对象和类同名,不会产生命名冲突是因为scala的两个命名空间,值空间和类型空间,相互独立.

伴生对象和对应的类必须定义在同一源文件中,当在终端中定义时,使用 :paste 模式.

练习

写一个类Person的伴生对象,实现使用全名来初始化Person

Person类的定义如下

class Person(val firstname:String, val lastname:String) {
    def name = firstname + " " + lastname
}

val关键字将参数同时定义为类的属性值.

参考解答

object Person {
    def apply(fullname:String) = {
        val parts = fullname.split(" ")
        new Person(parts(0), parts(1))
    }
    // another constructor without parameters
    def apply() = new Person("yourfirstname","yourlastname")  
}

终端中验证

scala> val p = Person("hell ooo")
p: Person = Person@11ce2e22

scala> p.firstname
res13: String = hell

scala> p.lastname
res14: String = ooo

你可能感兴趣的:(essential scala: 伴生对象)