traitがある種の多重継承をサポートするなら、悪名高い"ダイヤモンド問題"に苦しむことになるのではないか。答えはもちろんノーです。Scalaは多重継承のヒエラルキーの中でいつ何が実行されるのか明確に決まっています。この規則は利用しているtraitの数とは関係ありません。この規則のおかげで、複雑な問題に邪魔されずに多重継承の利点を享受できるのです。次のコードはJava開発者には馴染みがあるでしょう。}}設計の観点から見ればロギングは横断的な関心事です。日々のJava開発の中ではそのような設計の観点を踏まえた実装はおほとんど見当たりません。各クラスでロガーを宣言しているのが実情です。この例ではログレベルをチェックするためにisDebugEnabled()メソッドを使っています。Yourself)に明らかに違反しています。Javaの場合、プログラマがログレベルのチェックを宣言していることは正当化できません。クラスに関連した適切なロガーを使う方法もありません。Java開発者はこの書き方に親しんでいます。今やひとつのパターンです。traitはこのパターンに対して優れた代替案を提供します。traitにロギング機能を持たせ、ログ出力を加えたいクラスにこのtraitをmix-inすることができます。することでクラスは‘ロギング’という横断的関心事にアクセスできます。traitを実装します。}}Scalaは‘trait’キーワードを使ってtraitを宣言します。traitの本体にはフィールドやメソッドなど抽象クラスで宣言できるものなら何でも含むことができます。traitを使っているクラスをロギングします。=>という構文は自己型(self-type)と呼ばれ、traitがそのtraitを使っているクラスを参照するときに使われます。Tを使っていることに注意してください。isDebugEnabled()でチェックしている理由はデバッグログレベルが有効なときだけ出力するStringを計算するようにするためです。debugメソッドが単純にStringの引数を受け取るだけだと、デバッグログレベルの有効、無効に関わらず出力する文字列を求めてしまいます。これは望ましくありません。Tを受け取ることで、望み通りの処理になります。関数msgはisDebugEnabledのチェックに通った場合のみ、出力する文字列を返します。isDebugEnabledのチェックに通らなかったとき、関数msgは呼ばれませんので、Stringを求めるという不必要な処理は実行されません。traitを使いたい場合、extendsを使います。me");}‘extends’キーワードがあるので、PhotoはLoggableから派生し、他のクラスは継承できないと思えますが、正しくありません。Scalaの構文ではクラスを拡張とtraitの利用に‘extends’を使います。traitを複数使いたいのなら、キーワード‘with’を使い、使いたいtraitを並べます。‘with’キーワードを使った例は後述します。Photoクラスのメソッドsave()を呼び出して、実際の動作を確かめてみましょう。meクラスに振る舞いを追加する前段で説明した通り、クラスは複数のtraitを利用できます。ロギングの他に、Photoクラスにさらに振る舞いを追加することができます。Photoをファイルの大きさ順に並べたいとしましょう。幸運なことに、Scalaの場合、たくさんのtraitが最初から使えます。traitがあります。OrderedはJavaのインターフェイスComparableに似ています。大きな違いはScalaのOrderedは実装も提供するということです。sizeKb)}上記の例では、ふたつのtraitが使われています。traitが使われています。traitを使うにはcompare(type:T)メソッドの実装が必要です。これもJavaのComparableに似ています。traitは多くのメソッドを提供します。これらのメソッドはオブジェクトを比較するための様々な方法を提供します。これらのメソッドはすべてcompareメソッドの実装を利用します。シンボルはJavaとは違い特別な予約語ではありません。traitがこれらのシンボルを使ったメソッドを実装しているからです。traitを実装したクラスはScalaのコレクションでソートできます。Orderedオブジェクトのコレクションで‘sorted’が呼ばれると、compareメソッドで定義された順に並び替えが行われます。上述した例では、traitを使うことでモジュール化の方式に従って汎用的な機能を分離することができることを示しました。分離した機能はその機能を必要とするクラスに追加することができます。traitを使えばいいのです。これのtraitは他のクラスで再利用可能です。Yourself)なコードを書ける強力な仕組みです。8の仕様のドラフトには仮想拡張メソッドの定義が含まれています。仮想拡張メソッドは既存のインターフェイスの既存のメソッドや新しいメソッドにデフォルトの実装を与えます。多くのインターフェイスが高階関数のかたちでラムダ式をサポートととても便利になります。java.util.Collectionインターフェイスを考えてみましょう。java.util.CollectionインターフェイスがforEach(lambdaExpr)メソッドを提供すればとても便利でしょう。このメソッドがデフォルトの実装なしに追加されたら、このインターフェイスを実装しているクラスはデフォルトの実装を書かなければなりません。この方法では互換性に大きな問題が発生するのは明らかです。これがJDKのチームが仮想拡張メソッドを導入しようとしている理由です。仮想拡張メソッドがあれば、例えばデフォルトの実装を含んだforEachメソッドをjava.util.Collectionに追加することができます。この場合、java.util.Collectionインターフェイスを実装しているすべてのクラスは自動的にforEachメソッドとデフォルトの実装を継承します。することで、インターフェイスを実装しているクラスに影響を与えずにAPIを成長させることができます。これが仮想拡張メソッドの目的です。デフォルトの実装が実装クラスに合わないものだったら、オーバーライドすればいいのです。traits仮想拡張メソッドの主な使い方はAPIの拡張です。仮想拡張メソッドは振る舞いの多重継承を提供します。Scalaのtraitは振る舞いだけでなく状態の多重継承も提供します。状態と振る舞いに加え、traitは実装クラスを参照できます。これはLoggableの‘self‘フィールドの例で見た通りです。使い方の観点から考えると、traitは仮想拡張メソッドよりも多くの機能を提供します。両者の目的は異なります。Scalaでは、traitは常に‘問題なく’多重継承を提供できるモジュールを提供するのが目的です。仮想拡張メソッドの第一の目的はAPIの進化を可能にすることであり、‘振る舞いの多重継承’は二の次です。traitを実装してみましょう。traitは仮想拡張メソッドで完全に実装できます。状態は関係ないからです。traitに対応するのはjava.lang.Comparableです。実装は次のようになるでしょう。}既存のComparableインターフェイスに比較のためのメソッドを追加してます(‘より大きい’、‘以上’、‘より小さい’、‘以下’の4つ。traitではそれぞれ、>、>=、<、<=)。デフォルトの実装はdefaultキーワードで印がついています。すべて既存の抽象メソッドcompareを呼び出しています。結果として、既存のインターフェイスは新しいメソッドで強化されたものの、Comparableを実装しているクラスはこれらの新しいメソッドを実装する必要はありません。traitはこの実装にとてもよく似ています。PhotoクラスがComparableを実装しているなら、次のようにこれらの新しいメソッドで比較処理を実現できます。traitは仮想拡張メソッドだけでは完全に実装できません。//etc...}この例では、Loggableインターフェイスにdebug、infoなどのログ出力メソッドを追加しています。デフォルトではこれらのメソッドの呼び出しはLoggerに移譲されています。この例にないのは実装クラスの参照を得る方法です。この仕組みがないので、Loggableインターフェイスをロガーとして使う必要があります。このロガーは実装クラスの代わりにLoggable上ですべての文を出力します。この制限があるので、仮想拡張メソッドはこの用途にはあまり向きません。traitと仮想拡張メソッドは両方とも振る舞いの多重継承を提供しますが、traitは状態の多重継承と実装クラスへの参照を提供します。8はさまざまな特徴が追加されます。これらの特徴はアプリケーション開発を根本的に変える可能性があります。ラムダ式のような関数型言語の特徴が取り込まれるのはパラダイムシフトだと考えられます。この変化は簡潔でコンパクトで簡単に理解できるコードを記述するための新たな可能性を提供します。ラムダ式は並列処理を有効に活用するためにも重要です。この記事で紹介したように、これらすべての特徴はすでにScalaで利用できます。8の早期ビルド版を試してみると言いでしょう。来るパラダイムシフトに備えてScalaを触ってみるのもいいかもしれません。8の情報は主に下記のプレゼンを参考にしました。Peter氏はXebiaのシニアコンサルタントです。10年間のIT業界の経験の中で氏は開発者からソフトウエアアーキテクト、チームリーダ、スクラムマスタなど多くの役割を果たして来ました。JVM上の様々な言語や開発手法、ツールについても理解を深めてきました。Enthusiastコミュニティ(DUSE)の議長でもあります。Bergは1999年よりITに従事しています。防衛産業のいくつかの会社でソフトウエア開発者として働き、主にMDA/MDDソリューションの開発に従事しました。2010年、シニアコンサルタントとしてXebiaに参画し、現在は同社でリーンアーキテクチャ手法とScalaの普及に従事しています。氏はアーキテクチャ以外に言語の設計にも興味を持ち、複数の関数型言語のコミュニティが活動しています。氏は難しい問題をエレガントに解決するのが好きです。Clojure、Haskell、F#にも親しんでいます。毎週火曜日に前週のまとめコンテンツがお送りいたします。25万人ものシニアデベロッパーのコミュニティーにぜひご参加ください。サンプルを見るあなたのメールアドレスはこちら国を選んでください。プライバシーポリシーに従って私の個人情報を扱うことに同意します。登録するとさまざまなことができます。アカウント登録をしてInfoQをお楽しみください。あなたの意見をお聞かせください。/スパムの可能性があると認識されました。モデレーターが確認し問題がなければ24時間以内に公開します。その際あなたへの通知は行われませんのでご了承ください。8の情報は主に書きのプレゼンを参考にしました。8の情報は主に下記のプレゼンを参考にしました。毎週火曜日に前週のまとめコンテンツがお送りいたします。25万人ものシニアデベロッパーのコミュニティーにぜひご参加ください。サンプルを見る様々なイノベーターとアーリーアダプターがお送りするテクノロジーの概要を見る。自分がまだ知らないことに気づいていないと知るあなたが興味のあるトピックスをいつでも最新な情報に。あなたのメールアドレスはこちら国を選んでください。プライバシーポリシーに従って私の個人情報を扱うことに同意します。よい世界へ私たちが暮らす世界を大切に思い、よりよいものにしたいと考えています。人のためのソフトウェア開発を加速し私たちのミッションを実現することで、この思いを成し遂げようとしています。私たちは利益の1%をさまざまな慈善団体に寄付しています。会社として、また従業員��して、そうしたことの価値を強く信じているからです。with.プライバシーBTあなたのプロファイルは最新ですか?プロフィールを確認してアップデートしてください。アドレス*Eメールを変更すると確認のメールが配信されます。会社名:現在の会社名をご入力ください。Other組織規模:現在の組織規模をご入力ください。2,501+国:現在の国を設定してください。Zimbabwe都道府県:現在の都道府県に設定してください。次の都道府県にアップデートする:ニュースレターを購読しますか?インダストリーメールを購読しますか?本Eメールに登録すると、以前より関心のあったトピックの関連情報をお送りする場合がございます。詳細はこちらのプライバシーポリシーをご覧ください。newsletter?新しいメールアドレスに確認用のメールを送信します。このポップアップ画面は自動的に閉じられます。