Javaには、java.util.Listという一般的なリストを表現するためのインターフェイスがあります。そして、APIリファレンスのList(Java Platform SE 6)にある既知の実装クラスの一覧を見ると分かるのですが、実はjava.util.ArrayListとjava.util.LinkedListはどちらもjava.util.Listインターフェイスを実装(implements)しています。
この意味するところは、「java.util.ArrayList もjava.util.LinkedListもリスト(java.util.List)として扱えます」ということになります。そして、add メソッド、sizeメソッド、getメソッドはどれもjava.util.Listのメソッドなので、Sample90のexecuteメソッドは次のように書き換えができます。
java.util.List list = new java.util.ArrayList(); list.add("A"); list.add("B"); for (int i = 0 ; i < list.size() ; i++) { String s = (String)list.get(i); System.out.print(s + " "); } System.out.println(""); list = new java.util.LinkedList(); list.add("A"); list.add("B"); for (int i = 0 ; i < list.size() ; i++) { String s = (String)list.get(i); System.out.print(s + " "); } System.out.println("");
もちろん、行き当たりばったりでは、このようにうまくはいきません。今回は、最初からjava.util.Listを使えるように、説明の都合上仕組んであったので、うまく書き換えができるのです。
「java.util.List list = new java.util.ArrayList();」「list = new java.util.LinkedList();」の部分に注目をしてください。繰り返しになりますが、「java.util.ArrayListもjava.util.LinkedListもリスト(java.util.List)として扱える」ということから、こういったことができるのです。new演算子によって生成されているインスタンスのクラスは違いますが、インターフェイスを使うことで同じ変数名listで参照できる点が便利なのです。
インターフェイスを使うことにより、重複するコードが出てきたので、その分をメソッドとしてまとめることにしましょう。次のように、新しいlistメソッドを作成します。どうでしょうか。最初に示したコードに比べて、ずいぶんとスリムになりました。
public class Sample91 { public static void main(String[] args) { new Sample91().execute(); } public void execute() { list(new java.util.ArrayList()); list(new java.util.LinkedList()); } public void list(java.util.List list) { list.add("A"); list.add("B"); for (int i = 0 ; i < list.size() ; i++) { String s = (String)list.get(i); System.out.print(s + " "); } System.out.println(""); } }
list()メソッドではjava.util.Listインターフェイス型の仮引数listが宣言されています。このため、このlistへはjava.util.ArrayList型のインスタンスやjava.util.LinkedList型のインスタンスを渡すことができます。このようにして、利用するクラスを簡単に変更できるように、メソッドを書くことができるわけです。
インターフェイスの使い方について理解したところで、次はインターフェイスを自作する方法について見てみましょう。
最初に「インターフェイスとは、具体的な処理が書かれていないメソッドの型だけを宣言している特別なクラスのようなものです」と説明しました。このことから分かるように、インターフェイスは基本的に、メソッドの型だけを宣言します。文法的には、次のように表記します。
interface インターフェイス名 { メソッドの宣言 }
フィールドの宣言もできますが、本連載では基本を押さえることに専念しましょう。
メソッドの宣言については、次のようになります。連載第7回の「クラスの振る舞いを表すJavaの“メソッド”とは?」で紹介したように、クラスでのメソッド宣言では処理を記述するために「{ 処理 }」という部分がありましたが、インターフェイスのメソッド宣言では、この部分はありません。これは、インターフェイスでは実際の処理は必要ないからです。
戻り型 メソッド名(仮パラメータ型 仮パラメータ名);
void メソッド名(仮パラメータ型 仮パラメータ名);
ここでは、仮パラメータを1つ持つメソッドで、戻り型を持つものとvoid型のものだけを紹介しましたが、仮パラメータがないメソッドや複数の仮パラメータを持つメソッドなども宣言できます。その場合は「{ 処理 }」がないというのは同じです。もちろん複数メソッドの宣言もできます。
ここで、連載第7回で作成したDiceクラスを思い出してみましょう。
最初に、Diceクラスは「int roll()」というメソッドを持つように設計をしました。その後で、「イカサマサイコロ」と「通常のサイコロ」の2つの実装方法を紹介しました。第7回の時点ではDiceクラスのプログラムコードを直接書き換えましたが、インターフェイスを使えば、両方とも用意して切り替えを簡単にできるようになります。今回はインターフェイスを使って、このDiceを実現してみましょう。
Eclipseの操作手順は以下のとおりです。まずは、DiceIFインターフェイスを作成してみましょう。
出来上がったインターフェイスDiceIFはメソッド「int roll()」を持つので、このメソッドを宣言します。つまり、次のように編集します。
public interface DiceIF { public int roll(); }
文法解説のときには付けませんでしたが、interfaceとメソッド宣言の前に「public」という修飾子が付いています。これらについては、ここではおまじないだと思って付けてください。
次ページでは、引き続きEcilpseでインターフェイスを実装したクラスを作って使う方法を説明します。また、インターフェイス継承と実装継承も紹介します。
Copyright © ITmedia, Inc. All Rights Reserved.