SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

今からでも遅くない これから始めるScala

今からでも遅くない これから始めるScala(後編)

進化したオブジェクト指向


トレイトによるMix-in

 Scalaには、トレイトというMix-Inのための仕組みが用意されています。トレイトは、実装を持つことができるインターフェイス、あるいは多重継承を許可する抽象クラスとも言えます。

 さっそくトレイトの例を見てみましょう。リスト9では、JpDateFormatterとという日付を日本語に整形する機能を持つトレイトと、URLSourceLoaderというURLオブジェクトから文字列を読み出す機能を持つ、2つのトレイトを定義しています。

リスト9 トレイトの例
// 日付を日本語で整形する機能を持つトレイト
trait JpDateFormatter {
  import java.text.SimpleDateFormat

  // 日付を整形するメソッド
  def formatDate( d:Date ) = {
    val formatter = new SimpleDateFormat("yyyy年MM月dd日 HH時mm分ss秒")
    formatter.format( d )
  }
}

// URLから文字列を読み出す機能を持つトレイト
trait URLSourceLoader {
  import scala.io.Source
  val url:URL   // 抽象メンバー。このトレイトをMix-Inされるクラスで実装する

  // scala.io.Sourceオブジェクトを利用してurlから文字列で読み出す
  def load = Source.fromURL( url ).getLines().toSeq
}

 トレイトは、traitキーワードで定義します。objectと同様にコンストラクタは定義できませんが、メンバーを持つことが可能ですし、他のクラスやトレイトを継承させることもできます。JpDateFormatterトレイトは、formatDateという実装を持つメソッドを持っています。JpDateFormatterがMix-Inされる先のクラスでは、このformatDateメソッドが利用できるようになるわけです。

 URLSourceLoaderトレイトは、java.net.URL型の抽象メンバーurlを持っており、scala.io.Sourceクラスを利用してurlからネットワーク経由で文字列を読み出す機能を持ちます。

 URLSourceLoaderトレイトをMix-inするクラスでは、抽象メンバーurlを定義する必要があります。このように、メンバー名と型の宣言だけを行った場合は、抽象メンバーとして扱われます。フィールドだけでなくdefによる抽象メソッドも定義可能です。

 では、Bookmarkクラスにこの2つのトレイトをMix-Inしてみましょう。トレイトは、extendsとwithでMix-Inします。リスト1で示したScalaのクラス宣言の定義を思い出してください。

リスト10 BookmarkクラスにトレイトをMix-Inする
class Bookmark private ( val title:String, val url:URL, val date:Date ) extends JpDateFormatter with URLSourceLoader

// Bookmarkコンパニオンオブジェクト
object Bookmark {
// ...省略
}

 extendsキーワードでJpDateFormatterトレイトを指定しています。Bookmarkクラスはスーパークラスを持っていないので、最初のトレイトのMix-Inにはextendsキーワードを指定します。次に、withキーワードで、URLSourceLoaderトレイトを追加でMix-inしています。このほかにもトレイトをMix-Inさせたい場合は、続けて「with トレイト」とつなげていくことで複数のMix-Inが可能です。

 URLSourceLoaderトレイトで定義されていた抽象メンバーurlは、Bookmarkクラスのコンストラクタで受け取ってvalで公開されているurlフィールドによって実装されています。

 では、REPLで2つのトレイトを定義し、新しくトレイトをMix-InしたBookmarkクラスを再度定義して、動作確認しましょう。

リスト11 トレイトの動作確認
scala> trait JpDateFormatter {
       // ...省略
     | }
defined trait JpDateFormatter

scala> trait URLSourceLoader {
       // ...省略
     | }
defined trait URLSourceLoader

scala> object m{
     | class Bookmark private ( val title:String, val url:URL, val date:Date ) extends JpDateFormatter with URLSourceLoader
     |
     | // Bookmarkコンパニオンオブジェクト
     | object Bookmark {
       // ...省略
     | }
defined module m

scala> val bookmark = m.Bookmark("今から始めるScala 前編","http://codezine.jp/article/detail/5193/" )
bookmark: m.Bookmark = m$Bookmark@6dbd984

scala> bookmark.formatDate( bookmark.date )
res2: java.lang.String = 2010年06月18日 16時54分11秒

scala> bookmark.load
res3: Seq[String] = List(<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">, <html lang="ja">, <head>, <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">, <meta http-equiv="Content-Style-Type" content="text/css">, <meta http-equiv="Content-Script-Type" content="text/javascript">, <title>今からでも遅くない これから始めるScala(前編)(1/7):CodeZine</title>, ...

 Bookmarkクラスのインスタンスには、JpDateFormatterトレイトから継承したformatDateメソッドやURLSourceLoaderトレイトから継承したloadメソッドが利用できるようになっていることが分かると思います。

 このように、トレイトを利用することで複数の実装を持つトレイトをクラスにMix-Inさせてさまざまな機能を追加できるようになります。

次のページ
パターンマッチ

この記事は参考になりましたか?

今からでも遅くない これから始めるScala連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 尾崎 智仁(オザキ トモヒト)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/5329 2010/08/08 00:57

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー