それが僕には楽しかったんです。

僕と MySQL と時々 MariaDB

全てのプログラマに捧げるScala入門 トレイト

はじめに

Scalaで規模の大きいプログラムを作成する場合にモジュール化するのは非常に重要なことである。
そこでモジュール化のための機能をココでは紹介する。
JavaにおけるInterfaceと同等の機能を持つtraitである。

トレイト

トレイトとは次の様に宣言する。

trait Name{
}

宣言自体はtraitというキーワードを使うだけなので宣言は比較的簡単である。
それでこのトレイトで何が出来るかというとメソッドとフィールドの定義を持つことができる。
ScalaのトレイトはほとんどJavaのInterfaceと同じであるが、決定的に違う点がある。

それはinterfaceの様な機能を持ちながら、メソッドが宣言のみで処理を持たないものだけでなく
実装をもったメソッドも含めることが出来るという点である。

実装をもつメソッドも含めるということはそれだけ機能を抽象化するだけでなく
カプセル化できるという利点がある。

では実際に自身がTwitter4SというScalaで書いたTwitterAPIのラッパーライブラリ内で使用しているトレイトを例に挙げてみよう。

trait StatusBase {

  /**
    * @param text
    * @return response json as Status
    */
  def updateStatus(text: String): Status

}

実際に処理がない宣言のみのメソッドを持っているがこれはエラーにならずトレイトの要素として認められる。
上記のメソッドには実装がないため、このトレイトをミックスインしたクラスでオーバーライドしなければならない。


それではクラスとほとんど変わらないのでは?と思うかも知れないが
クラスともまた違う点がある。それは次の点である。

最初の2つはともかくとして、ミックスインはモジュール化やトレイトを使う上で重要なので説明していく

ミックスイン

クラスにトレイトを実装する場合やトレイト自身に別のトレイトを継承(厳密にはこれもミックスインというが)することをミックスイン合成という。

どのように使うかというと次のように使う。

trait TraitA

class Sample extends TraitA //これはミックスイン
class SubSample extends Sample with TraitA // withキーワードでもミックスインとなる

//traitにtraitをミックスインする場合
trait TraitB extends TraitA
trait TraitC extends TraitA with TraitB

1つめでミックスインするならextends、ふたつ目以降はwithキーワードを使う。
ただしクラスを継承する場合は優先的にextendsを使わないとエラーとなる。

ここまで聞くと、インスタンス生成やコンストラクタを持てないクラスが多重継承できると思うが(クラスは多重継承できない)
実際に多重継承でなくても、実質的に多重継承の様な機能を持っていることになる。


この性質がもたらす問題について別の記事で解説していく。
詳しくはドワンゴScalaドキュメント等を見て欲しい。

おわりに

ここまでで、大規模なコードを書く上で重要なモジュール化の役割を果たすトレイトについて解説した
次は、ラムダや高階関数、カリー化についてまとめる。