Help us understand the problem. What is going on with this article?

コンパニオンオブジェクトとは

More than 1 year has passed since last update.

概要

Scalaではオブジェクトとクラスに同じ名前を付けることが可能です。このようなオブジェクトを コンパニオンオブジェクト と呼びます。
明確に定義すると「同一ファイル内・同一パッケージ内でクラスと同じ名前で定義されたオブジェクト」といえます。
以下の例では、コンパニオンオブジェクトにUSDJPYなどのメンバーを定義しており、それらはインスタンス化前から利用できます。
またコンパニオンクラスとコンパニオンオブジェクトのお互いは、下記のDefaultCurrencyのようにメンバーがprivateであったとしても、アクセス( 特権アクセス と呼びます)できます。

Money.scala
import java.util.{ Currency, Locale }

class Money(val amount: BigDecimal, val currency: Currency = Money.DefaultCurrency) {

    def add(other: Money): Money =
        new Money(amount + other.amount, currency)

    def subtract(other: Money): Money =
        new Money(amount - other.amount, currency)

    def asString: String = s"${currency.getSymbol}$amount"

    def +(other: Money): Money = add(other)
    def -(other: Money): Money = subtract(other)

}

object Money {

    // 日本円の通貨単位
    val JPY = Currency.getInstance("JPY")
    // USドルの通貨単位
    val USD = Currency.getInstance("USD")
    // デフォルトの通貨単位
    private val DefaultCurrency = Currency.getInstance(Locale.getDefault)

    // ファクトリ責務としてのapply
    def apply(amount : BigDecimal, currency : Currency): Money = new Money(amount, currency)
    def apply(amount : BigDecimal): Money = new Money(amount)

}

object Money_main {
    def main(args: Array[String]): Unit = {
        val money1: Money = Money.apply(100, Money.JPY)
        val money2: Money = Money.apply(200, Money.USD)
        val money3: Money = Money.apply(300)
        // applyを省略して記述できます。こちらの記述を慣習的に多く使います
        val money4: Money = Money(100, Money.JPY)   // new Money(100, Money.JPY) とするよりも短く書ける
        val money5: Money = Money(200, Money.USD)   // new Money(200, Money.USD) とするよりも短く書ける
        val money6: Money = Money(300)              // new Money(300)            とするよりも短く書ける
    }

}

コンパニオンオブジェクトの存在意義

コンパニオンオブジェクトには、さまざまなメソッドが定義できますが、よく利用する一例としてファクトリ(インスタンスの生成)があります。
上記のようにapplyメソッドを定義することで、new演算子を利用せずにインスタンスを作ることができます。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away