scala单例object与伴生object入门

概念

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方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值