プログラムを「変更」しやすくする“インターフェイス”【改訂版】Eclipseではじめるプログラミング(9)(3/3 ページ)

» 2009年07月23日 00時00分 公開
[小山博史株式会社ガリレオ]
前のページへ 1|2|3       

Eclipseでインターフェイスを実装したクラスを作るには

 次に、このDiceIFを実装するクラスとして「いかさまダイスのFakeDice」と「本物ダイスのRealDice」を作成します。まず、次のようにFakeDiceクラスを作成します。

  1. [パッケージ・エクスプローラー]の[Sample]をマウス右ボタンでクリック
  2. 表示されるポップアップメニューで[新規]→[クラス]を指定
  3. 表示される[新規Javaクラス]ダイアログで、[名前]に「FakeDice」と入力
  4. [追加]ボタンをクリック
  5. 表示される[インプリメントされたインターフェイスの選択]ダイアログで[インターフェイスを選択してください]の欄に「DiceIF」と入力(図3
  6. [OK]ボタンをクリック
  7. [新規Javaクラス]ダイアログで、[インターフェイス]にDiceIFが追加されたことと、[どのメソッド・スタブを作成しますか?]のところにある[public static void main(String[] args)]のチェックが付いていないことを確認(図4
  8. [終了]ボタンをクリック
図3 表示される[インプリメントされたインターフェイスの選択]ダイアログで[インターフェイスを選択してください]の欄に「DiceIF」と入力 図3 表示される[インプリメントされたインターフェイスの選択]ダイアログで[インターフェイスを選択してください]の欄に「DiceIF」と入力
図4 [新規Javaクラス]ダイアログで、[インターフェイス]にDiceIFが追加されたことと、[どのメソッド・スタブを作成しますか?]のところにある[public static void main(String[] args)]のチェックが付いていないことを確認 図4 [新規Javaクラス]ダイアログで、[インターフェイス]にDiceIFが追加されたことと、[どのメソッド・スタブを作成しますか?]のところにある[public static void main(String[] args)]のチェックが付いていないことを確認

 同様にしてRealDiceクラスを作成します。生成されたFakeDiceクラスとRealDiceクラスへフィールドを追加し、「public int roll() { }」内の処理を変更します。具体的には、次のように修正します。

public class FakeDice implements DiceIF {
    int[] values = new int[] {
        3, 4, 2, 1, 5, 6
    };
    int current = 0;
    @Override
    public int roll() {
        current++;
        if (current == 6) current = 0;
        return values[current];
    }
}
FakeDice.java
public class RealDice implements DiceIF {
    java.util.Random r = new java.util.Random();
    int maxNum = 6;
 
    @Override
    public int roll() {
        return r.nextInt(maxNum) + 1;
    }
}
RealDice.java

コラム 「アノテーションについて簡単に触れておく」

生成されたコードに「@Override」という行がありますが、これはアノテーションです。アノテーションの詳細は、後ほど別途解説をする予定ですが、簡単に説明をしておきます。

このアノテーションは、「インターフェイスで宣言されているメソッドを実装している」という注釈をプログラムに付けています。ここでは、DiceIFインターフェイスのroll()メソッドを実装しているという印を付けているのです。この注釈はプログラムの実行には影響がありません。


 なお、ほかのコードの内容についての解説は連載第7回のものと同じなので、そちらを参照してください。

インターフェイスを実装したクラスを使ってみる

 最後に、これらを使用するサンプルクラスSample92を作成します。

  1. [パッケージ・エクスプローラー]の[Sample]をマウス右ボタンでクリック
  2. 表示されるポップアップメニューで[新規]→[クラス]を指定
  3. 表示される[新規Javaクラス]ダイアログで、[名前]に「Sample92」と入力
  4. 同じ[新規Javaクラス]ダイアログで、[どのメソッド・スタブを作成しますか?]のところにある[public static void main(String[] args)]をチェックする
  5. [終了]ボタンをクリック

 java.util.Listを使ったときと同様にして、DiceIFインターフェイスをパラメータとして持つメソッドrollsを用意して実行します。rollsメソッドでは単純に6回ダイスを振って、その結果を出力するという処理となっています。FakeDiceを使いたいときには、rollsへFakeDiceオブジェクトを渡しますし、RealDiceを使いたいときには、rollsへRealDiceオブジェクトを渡しています。

public class Sample92 {
    public static void main(String[] args) {
        Sample92 app = new Sample92();
        System.out.println("FakeDice");
        app.rolls(new FakeDice());
        System.out.println("RealDice");
        app.rolls(new RealDice());
    }
 
    public void rolls(DiceIF dice) {
        for (int i=0 ; i<6 ; i++) {
            System.out.println(dice.roll());
        }
    }
}
Sample92.java

 実行結果は下記のようになります。FakeDiceの結果は何度実行しても変わりませんが、RealDiceの結果は実行するたびに変わっているはずです。

  Sample92.javaの実行結果

 FakeDice
 4
 2
 1
 5
 6
 3
 RealDice
 6
 5
 2
 3
 1
Sample92.javaの実行結果

 いかがでしょうか。java.util.Listを使ったプログラムと同じようなプログラムを自作できました。このようにインターフェイスを使えば、Diceクラスのコードをいちいち書き換えなくても、FakeDiceとRealDiceを簡単に切り替えができることも理解できたと思います。

コラム 「“インターフェイス継承”と“実装継承”」

FakeDiceクラスもRealDiceクラスも、DiceIFインターフェイスをimplementsすることで、「int roll()というメソッドを持ち、メソッドの処理コードを記述している」ことが分かるようになっていました。このとき、「int roll()というメソッドを持つ」という点に着目した場合は、これらは「インターフェイス継承の関係にある」といいます。

つまり「FakeDiceもRealDiceもDiceIFのインターフェイス継承をしている」ということになります。Javaのimplementsでは、「インターフェイス継承と、インターフェイスの実装(メソッドの処理コード記述)をしている」という両方の意味を含んでいます。

似たような機能として、「実装継承」というものもあります。こちらは、インターフェイスの継承だけでなくインターフェイスを構成するメソッドの処理コード自体も継承します。これは、既存のクラスを機能拡張したい場合によく使います。例えば、java.util.ArrayListクラスを機能拡張して「getメソッドの処理が何回呼ばれたか」というメソッドを1つだけ追加したいというようなときに便利です。

こんなときにJavaでは、java.util.ArrayListと同じようなクラスを自作する必要はなく、「キーワード「extends」を使って、java.util.ArrayListが実装しているコードをそのまま継承して、差分だけコーディングする」という方法が取れます。ちなみに、Javaのextendsは、インターフェイス継承と実装継承のどちらも可能であるため、単に「継承」と訳されます。


「変更」に強いプログラムを作るために

 今回は、インターフェイスについて解説をしました。2つのインターフェイスのサンプルプログラムを通して、インターフェイスの便利さを理解してもらえたでしょうか。インターフェイスは重要な概念ですが奥が深いので、すぐにすべてを理解することは難しいと思います。

 まずは、JavaのAPIで用意されているクラスについて、インターフェイスを実装している場合は、ほかの似たようなクラスと簡単に切り替えができるようにインターフェイスを使えるようになってください。インターフェイスを使ったプログラミングの経験を積むと、自然と自作インターフェイスの設計ができるようになるはずです。インターフェイスを有効に活用できるようになると、「変更」に強いプログラミングができるようになります。ぜひ、積極的に使うようにしましょう。

 インターフェイスを使ったプログラミングができるようになると、同じ名前のクラスを作りたくなることが多くなります。例えば、本当はDiceという名前のインターフェイスを今回作りたかったのですが、DiceIFという名前で作成しました。第7回のときにすでにDiceクラスというものを作成してしまっていたため、同じ名前となるDiceインターフェイスを作成できなかったからです。

 こういった問題を解決するために、Javaには「パッケージ」という概念が導入されています。次回はこのパッケージについて解説する予定ですので、お楽しみに。

  今回作ったサンプルのソースコードはこちらからダウンロードできます。

筆者紹介

小山博史(こやま ひろし)

情報家電、コンピュータと教育の研究に従事する傍ら、オープンソースソフトウェア、Java技術の普及のための活動を行っている。長野県の地域コミュニティである、SSS(G)bugs(J)の活動へも参加している。

著書に「基礎Java」(インプレス)、共著に「Javaコレクションフレームワーク」(ソフトバンククリエイティブ)、そのほかに雑誌執筆多数。



「【改訂版】Eclipseではじめるプログラミング」バックナンバー
前のページへ 1|2|3       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。