scala在JAVA之上增加了很多深奥的关键,例如match、type、implicit,却抹除了我们无比熟悉的static关键字。既然没有static,那我们怎么在scala中定义类的静态方法与属性呢?
真要做起来,其实比JAVA还绕(scala真的简洁吗?),具体分为以下两步:
1. 在这个类的同一份文件中添加伴生对象,也就是同名的object,注意一定要在同一份文件中;
2. 在伴生对象定义方法与属性,这样就可以通过类名(对象名)来访问属性与方法了;
举个简单的例子,如下:
// 定义了私有属性
class People(private val username: String) {
}
object People {
// 伴生对象可以访问私有属性
def welcome(self: People): String = {
s"Hello, ${self.username}!"
}
}
单元测试代码如下:
class PeopleTest extends FunSuite {
test("welcome show equals") {
val p = new People("yiifaa")
// scala中==可以比较值,不比较地址
assert(People.welcome(p) == "Hello, yiifaa!")
}
}
从上面的代码可以看出:
1. 伴生对象可以访问类的私有属性(同一份文件中的其他对象与类也不可以);
2. 伴生对象无法访问类的上下文,即this;
如果将代码改进下,我们还发现,伴生对象与类还具有如下关系:
3. 类也可以访问伴生对象的私有属性;
4. 伴生对象对所有的实例而言,都是共享的(独一份),就跟JAVA中类属性一模一样;
class People(private val username: String) {
// 引入People伴生对象的全部对象与方法
import People。._
// 也可以携带名称访问,如People.showname(this)
def show = showname(this)
}
object People {
// 定义私有方法
private def showname(self: People): Unit = {
println(self.username)
}
def welcome(self: People): String = {
s"Hello, ${self.username}!"
}
}
结论
scala可以通过伴生对象实现static的作用,在这一点上,跟JAVA相比,scala毫无优势,并且性能还略有损耗,毕竟类方法的执行效率高于实例方法,但在单例模式上,scala就是从语法上支持,比JAVA快捷太多了。