Scala之伴生类,伴生对象

package com.uplooking.bigdata.p2
 
/**
  * scala中关于伴生对象和伴生类的说明
  * 要想让伴生类和伴生对象创建的相关对象访问相应的成员,需要在伴生类和伴生对象中创建一个方法apply
  * 在伴生对象中要创建,实际apply最好写上括号,在用伴生对象创建对象的时候就可以省略new关键字
  * 在apply方法中,创建一个伴生类的对象即可
  */
object CompanionObjectOps {
  def main(args: Array[String]): Unit = {
    val customer = new Customer()//通过伴生类来创建的对象
    val customer1 = Customer() //这是通过伴生对象来创建的对象--->其实质还是调用了ojbect Customer中的apply()方法
    val money = customer.withdraw(2000)
    println(money)
//    customer1.apply.withdraw(200)
//    customer.apply.save()
//    customer.
    customer1.withdraw(200)
  }
}
 
/**
  * 所谓伴生对象,就是和某一个class同名的object,并且这个class和object必须在同一个scala源文件中存在,
  * 依次来满足类似于java中的一个类中既可以有静态的成员,也可以有非静态的成员
  * 把这个object就叫做了这个class的伴生对象
  * 把这个class就叫做了这个object的伴生类
  *
  * 在伴生类和伴生对象中可以互相调用互相的私有成员
  */
class Customer {
  private var cAccount = Customer.account
 
  def withdraw(money:Double): Double = {
    if(money > cAccount) {
      throw new RuntimeException("余额不足,请确认后再取钱~")
    }
    cAccount -= money
    println("当前账户余额:" + cAccount + "¥")
    money
  }
 
  def apply():Customer = {
    println("---------customer apply------------")
    val c = Customer()
    c
  }
}
 
object Customer {
  private var account = 5000.0
 
  def save(money:Double): Unit = {
    account += money
    println("当前账户余额:" + account + "¥")
  }
  //在伴生对象中写一个方法apply,然后就可以在伴生对象中调用伴生类中的成员,返回值为伴生类
  //
  def apply(): Customer = new Customer()
}
<think>好的,用户想了解Scala伴生对象的apply方法的作用用法。首先,我需要回忆一下Scala的基础知识,伴生对象的关系。伴生对象同名,并且位于同一个文件中,可以互相访问私有成员。伴生对象似于Java中的静态方法,但Scala没有static关键字,所以用伴生对象来实现似的功能。 接下来,apply方法。记得apply方法在Scala中是一个特殊的方法,当对象后面加上括号时会被调用。例如,Object(args)会调用Object.apply(args)。伴生对象中的apply方法通常用于构造的实例,这样可以省略new关键字,使代码更简洁。 用户提到的引用[2]里提到伴生对象可以定义apply方法来创建链式结构,传递块列表。这说明apply方法可以作为一种工厂方法,封装对象的创建逻辑。比如,List.apply(1,2,3)创建一个列表,而不需要new List。 需要解释apply方法的作用:提供简洁的实例创建方式,隐藏实现细节,支持多种重载的构造方式。然后,用法方面,可以在伴生对象中定义apply方法,返回的实例。用户使用时直接调用伴生对象名加参数,而不需要new。 可能用户还想知道apply方法的好处,比如更函数式的风格,统一对象创建接口,或者配合模式匹配使用。还要注意apply方法可以有不同的参数列表,提供多种构造方式。 然后,结合用户的引用,引用[2]中的例子,伴生对象的apply方法用于创建Chain实例,传递blocks列表。这样用户可以通过Chain(blocks)来创建实例,而不是new Chain(blocks)。 另外,需要提到apply方法在集合中的广泛应用,比如List、Array等,都是通过伴生对象的apply方法来实例化。这也是Scala的惯用法。 可能还需要对比Java的静态工厂方法,说明Scala中通过伴生对象apply方法实现似的效果,但语法更简洁。 总结回答结构:先介绍伴生对象,然后apply方法的作用,接着具体用法例子,最后总结优点应用场景。确保使用中文,行内公式用$...$,独立公式用$$...$$,不过这里可能用不上太多数学公式,但如果有相关例子的话要注意格式。 检查是否有遗漏,比如是否需要提到unapply方法,但用户的问题主要关注apply,所以可能不需要展开。确保引用正确,引用[2]提到伴生对象的apply方法用于创建实例,所以引用标识放在相关段落末尾。</think>### Scala伴生对象apply方法的作用与用法 #### 1. 伴生对象基础 在Scala中,**伴生对象**(Companion Object)是与同名且位于同一文件中的单例对象。它可以互相访问私有成员,似于Java中静态方法的容器,但更灵活[^2]。例如: ```scala class Person(val name: String) object Person { def defaultName = "Unknown" // 似静态方法 } ``` #### 2. apply方法的核心作用 `apply`方法是Scala的语法糖,允许**省略new关键字**直接创建对象实例。当调用`ClassName(args)`时,实际会触发伴生对象的`apply`方法。例如: ```scala class Chain(blocks: List[String]) object Chain { def apply(blocks: List[String]): Chain = new Chain(blocks) // 工厂方法 } // 使用方式 val chain = Chain(List("block1", "block2")) // 等价于 Chain.apply(...) ``` #### 3. 典型应用场景 - **简化对象构造** 隐藏具体实现细节,例如集合的创建: ```scala val list = List(1,2,3) // 实际调用List.apply(1,2,3) ``` - **支持多态构造** 通过重载实现不同参数列表: ```scala object Logger { def apply(level: String): Logger = new FileLogger(level) def apply(priority: Int): Logger = new NetworkLogger(priority) } ``` - **模式匹配支持** 结合`unapply`方法实现解构: ```scala case class User(name: String) // 自动生成User.applyUser.unapply ``` #### 4. 性能优势 通过伴生对象`apply`方法创建对象,**不会引入额外开销**。编译后会直接转换为标准构造函数调用,例如`Chain.apply(...)`会被优化为`new Chain(...)`。 #### 5. 设计模式对比 | 模式 | Java实现 | Scala实现 | |-------------|-------------------|------------------------| | 工厂方法 | 静态工厂 | 伴生对象apply方法 | | 单例模式 | static getInstance | 直接使用object关键字 | | 多态构造 | 重载构造函数 | 重载apply方法 | #### 6. 代码示例扩展 ```scala // 带逻辑的apply方法 object Connection { private val maxCount = 5 private var count = 0 def apply(): Connection = { if(count < maxCount) { count += 1 new Connection() } else throw new Exception("连接池耗尽") } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值