当前位置: 首页 > Scala, 程序代码 > 正文

Scala语音备忘拾遗_5 – 对象(Object) 伴生对象 伴生类

Scala语音备忘拾遗_5 – 对象(Object) 伴生对象 伴生类

Scala没有静态方法或字段,对象(Object)语法可以用来实现Java中的静态类/方法/字段.同时对象提供了更多特性.

1. 作为单例对象

  • 对象(Object)定义了某个类的单例实例,调用对象的方法时,使用对象名直接调用.
  • 对象也有构造器,在该对象第一次被使用时调用.
  • 对象本质上可以拥有类的所有特性,只有一个例外:你不能提供构对象造器参数.
  • 对象通常时作为存放工具函数或常量的地方,可高效地共享单个不可变实例。
package com.jack.yin

object TestAccount {
  val TEST_CONSTANT = "TEST_CONSTANT"
  private var lastNumber = 0

  def newUniqueNumber() = {lastNumber += 1; lastNumber}
}

object TestObject extends App {
  println(TestAccount.newUniqueNumber()) // 1
  println(TestAccount.newUniqueNumber()) // 2
  println(TestAccount.TEST_CONSTANT)  // 存放常量
}

2. 作为伴生对象

  • 同一源文件中定义的同名的class和object,class是object的伴生类,object是class的伴生对象.
  • 类和它的伴生对象可以相互访问私有特性,它们必须存在于同一个源文件中.
  • 伴生类中调用伴生对象方法需要使用伴生对象名作为前缀调用.
class Account(var name:String,var balance:Int) {
  private val privateFieldInClass = "privateFieldInClass"

  def printInfo(): Unit ={
    println(s"${name} 's balance is ${balance}")
  }

  def invokeFunFromObject():Unit = {
    // 伴生类中调用伴生对象方法需要使用伴生对象名作为前缀调用
    Account.printInfoInObj()
  }

  override def toString = s"Account($name, $balance)"
}

object  Account {
  def apply(name:String,num:Int) = {
    new Account(name,num)
  }

  // object方法,相当于定义一个静态方法
  def staticFunc():Unit = {
    println("staticFunc")
  }

  def printInfoInObj(): Unit = {
    // 直接 new 出对象
    val account = new Account("aaa",2)
    println(account)
    // 可以访问class 中的private 字段,但是 object 必须和 class定义在同一个文件中
    println(s"${account.privateFieldInClass} ")
  }

  def printInfoInObj_2(): Unit = {
    // 调用 apply方法
    val account = Account("aaa",2)
    println(account)
    // 可以访问class 中的private 字段,但是 object 必须和 class定义在同一个文件中
    println(s"${account.privateFieldInClass} ")
  }
}

3. apply方法简化构造类的实例

如下所示, 伴生对象定义了方法apply(),方法接受参数,返回Account实例,可以使用 var account = Account("Jack",24) 来构造一个account实例.
这里省略了new,因为正常情况下,使用构造函数生成一个实例的调用方式为 var account = new Account("Jack",24)

def apply(name:String,num:Int) = {
    new Account(name,num)
  }

4. 对象可以扩展类或特质

abstract class UndoableAction(val desc:String) {
  def undo():Unit
  def redo():Unit
}

// 这里继承UndoableAction 时指定了构造参数,看起来像继承了一个`抽象类的实例`
object DoNothingAction extends UndoableAction("Do Nothing") {
  override def undo(): Unit = {}

  override def redo(): Unit = {}
}

5. 应用程序对象

通常,一个scala程序的起点是一个object中的main方法. 也可以用一个object继承App特质,然后将代码放入构造器方法内.
如果需要命令行参数,可以通过args属性得到.
注: 定义一个类/对象的大括号内的所有语句都属于构造器方法的方法体.

object Hello extends App {
  if(args.length > 0) {
    println(f"Hello ${args[0]}")
  } else {
    println("Hello World!")
  }
}
赞 赏

   微信赞赏  支付宝赞赏


本文固定链接: https://www.jack-yin.com/coding/3191.html | 边城网事

该日志由 边城网事 于2020年07月06日发表在 Scala, 程序代码 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: Scala语音备忘拾遗_5 – 对象(Object) 伴生对象 伴生类 | 边城网事
【上一篇】
【下一篇】

Scala语音备忘拾遗_5 – 对象(Object) 伴生对象 伴生类 暂无评论

发表评论

快捷键:Ctrl+Enter