羽生田栄一(はにゅうだ えいいち)
株式会社豆蔵 取締役・プロフェッショナルフェロー
 モデリングやソフトウエア工学の実践適用に関するコンサル・教育を通じて後進の育成にあたる。現在,アジャイルプロセス協議会会長,SEC要求設計技術部会委員,パターンワーキンググループ主査,情報処理学会ソフトウェア工学研究会主査,IPA ITアーキテクト・コミュニティ委員などを務める。路地・トマソン物件・神社・富士塚・古書店等を巡る街歩きが趣味。オブジェクト指向技術関連の著書・訳書多数。技術士(情報工学部門)。

はじめに

 前回はScala言語の特徴とクラス定義の仕方をJavaとの比較をしながら説明しました。今回はさらに突っ込んで,Scalaの文法的な特徴をミニツアーという形で探検していきたいと思います。

 Javaのインターフェースに代わるtraitを用いるmixin型多重継承,型階層とコレクションの紹介をしていきます。

Traitでmix-in型の多重継承を

 ScalaにはJavaのインターフェースにあたるものとしてtraitがあります。traitとは特質とか形質という意味の英語です。実はtraitはJavaのインターフェースよりも強力です。インターフェースと違い,属性や操作の実装(メソッドの中身)を定義することもできるからです。Scalaでは,traitを単一の目的機能に奉仕するモジュールの部品化に利用します。そのような部品群をミックスインして組み合わせることにより各アプリケーションで必要なニーズに応えていこうという発想でScalaは設計されているのです。

 Scalaでは通常のクラスは単一継承しか認められていませんが,traitを多重継承(ミックスイン)することができ,結果として多重継承が実現できます。これは,Rubyのモジュールとほぼ同じ機能だと考えてよいでしょう。以下例を見てみます。ここではわかりやすさのために,traitの名前はTで始めるようにしています。traitはクラスを継承することでも他のtraitを継承することでも定義できます。

class Person ;   //実験用の空クラス(前回のPersonクラスを使う場合は,
                 //以下のPianoplayingTeacherにコンストラクタ引数が必要)
trait TTeacher extends Person {
    def teach   //実装を伴わないバーチャルなメソッド
}
trait TPianoPlayer extends Person {
    def playPiano = {println(“I’m playing piano. “)}  //実装を伴う具象メソッド
}
class PianoplayingTeacher extends Person with TTeacher with TPianoPlayer {
  def teach = {println(“I’m teaching students. “)}  //操作teachの実装を定義
}

 このように,traitはwith節を何個も連ねて複数のtraitをmixinしたクラスを定義することができるわけです。1個目の継承元はextendsで指定し,2個目以降はwith節で指定します。もうおわかりのように,インスタンスを生成可能なのはabstractでないクラスのみです。traitから直接インスタンス生成はできないことに気をつけてください。

 では実際に実行してみましょう。

scala> val t1 = new PianoplayingTeacher
t1: PianoplayingTeacher = PianoplayingTeacher@1e26d42
scala> t1.playPiano
I'm playing piano.
scala> t1.teach
I'm teaching students.

 実は,インスタンス生成時にそのオブジェクトに対して個別にtraitの性質を与えることもできます。

scala> val tanakaTaro = new Person with TTeacher with TPianoPlayer { def     teach = {println("I'm teaching students.")} }
tanakaTaro: Person with TTeacher with TPianoPlayer = $anon$1@13b8f62
scala> tanakaTaro teach
I'm teaching students.
scala> tanakaTaro playPiano
I'm playing piano.