minimize

事業拡大のため、新しい仲間を募集しています。
→詳しくはこちら

object の様々な使い方

Scala では、Java の Class や Interface を実装した object も定義できる。
これはどういう事か。以下のコードを見てみよう。

object PCL
  extends java.beans.PropertyChangeListener
{
  override def propertyChange(pce:java.beans.PropertyChangeEvent):Unit =
  {
      System.out.println("Bean changed its " + pce.getPropertyName() +
          " from " + pce.getOldValue() +
          " to " + pce.getNewValue())
  }
}

PropertyChangeListener を実装した PCL というオブジェクトを定義している。
Java の感覚で言えば、こういったものはクラスで定義するのが自然だろう。
ではなぜ object で定義するのか。
使う側のコードを見てみよう。

val p = new Person("Jennifer", "Aloi", 28)
p.addPropertyChangeListener(PCL)

このように、PCL をそのまま引数に渡している。
object は static であるから、こういった記述が可能となる。

Java では以下のようなコードになるだろうか。

p.addPropertyChangeListener(new PCL());

実際、両者にそんな大した差は無いと思う人もいるだろう。
確かに、コード量だけの面で言えば、両者に大差は無い。

では、メモリ消費量はどうだろう。
もし Person のインスタンスが100万個あった場合、PCL インスタンスも100万個生成される。
これはそれなりにメモリを消費することになる。

上の例で言えば、PCL は状態を保持するフィールドを持っていない。
つまりこれは object にしても問題ないということだ。
だとしたら、そうした方が優れているのではないだろうか。

object の apply

Scala では、apply という関数は特別な意味を持っている。

例えば scala.Array は class と object の両方を持っていて
object の方にも apply が定義されている。

def apply (x: Int, xs: Int*): Array[Int]

これはどう使うか。

Array(3, 4, 5)

このように使う。
こうすると、object である Array の適用(apply)関数を呼び出すことになる。

val hoges = new Array[Int](3)
hoges(0) = 3
hoges(1) = 4
hoges(2) = 5

こちらよりは前者の方がコードも短いし、読みやすい。