概念
object是一个特殊的类,特殊在这个类只有一个实例.并且是懒加载的,就是用到的时候才创建.
当对象定义于顶层时(即没有包含在其他类中),单例对象只有一个实例。
当对象定义在一个类或方法中时,单例对象表现得和惰性变量一样。
作用
为什么会有object这个概念,因为scala没有static关键字,无法创建单例,等原因
用法
singleton object
//object就是个单例,此处单例名字叫做Logger1.
object Logger1 {
def info(msg: String): Unit = println(s"INFO:$msg")
}
class MID {
//单例的方法可以像java中静态类的方法一样调用
Logger1.info("created objects");
}
object Test2 {
def main(args: Array[String]): Unit = {
//可以像调用静态类的方法一样调用object中的方法
Logger1.info("hello,world") //INFO:hello,world
//创建新的MID对象时
val m = new MID() //INFO:created objects
}
}
证明object是个单例的方式
object Test extends App {
//证明的确是个单例,因为创建2个是相同的
private val singletone1: Singletone.type = Singletone.getInstance()
private val singletone2: Singletone.type = Singletone.getInstance()
println((singletone1 == singletone2))//true
}
//obejct 本身就是个单例,把自己返回下就行了
object Singletone{
val singletone: Singletone.type =Singletone
def getInstance(): Singletone.type ={
singletone
}
}
Companion objects
scala中,与类名相同并且用object修饰的对象时 伴生对象.class和companion之间可以互相访问私有的方法和属性,他们必须在同一个源文件中
简而言之,就是可以互相访问,不管私有还是公有. 如果不是伴生对象,那只能是单例对象了,可以通过类名.方法
的形式访问
class Compaion {
var id = 0
private val name = "xiaohong"
private[this] var age = 18
private def getAge: Int = age
//访问伴生object的私有属性address
def getAddress(): Unit = println(Compaion.address)
}
object Compaion {
private val address = "beijing"
def main(args: Array[String]): Unit = {
val co = new Compaion()
//访问伴生class的属性id
co.id = 1
println(co.id) //1
//访问伴生class的属性name
println(co.name) //xiaohong
//访问伴生class的私有方法
println(co.getAge) //18
co.getAddress() //beijing
}
}
apply方法在伴生对象中的应用
用了后创建伴生class对象时可以少些个new,apply 方法在源码中的应用还是比较多的.
object Test extends App {
//创建对象时无需new,传参实际上传给了apply方法
val m=Man("李明",20)
m.showinfo()//李明 is 20 years old
}
//构造函数私有.这里其实有点像单例了
class Man private(name:String,age:Int){
def showinfo(): Unit ={
println(s"$name is $age years old")
}
}
//伴生object中定义apply方法,后续创建对象就会比较简单
object Man{
def apply(name: String, age: Int): Man = new Man(name, age)
}
如果是个case class,可以不用写apply方法,系统会自动在其伴生类中生成一个apply方法!
object Test extends App {
val m = Man("李明", 20)
m.showinfo() //李明 is 20 years old
}
case class Man private(name: String, age: Int) {
def showinfo(): Unit = {
println(s"$name is $age years old")
}
}
object Man {
}
App对象
可以不用写main方法就能执行,原理看源码
object HelloApp extends App{
println("hello world")//hello world
}
总结
- 单例object,像静态类一样用
- 伴生object,可以和伴生class互相访问
- apply方法,创建对象不需要new关键字!
- case class默认会给其伴生对象生成apply方法