Java.use(better); Episode#01 拡張可能な for 文(1)
■ Java: 拡張可能な for 文
プログラミング(作譜)の効率化を目指そうとしたとき、朗報に沸いたのが、J2SE 5.0(2004年)での「拡張 for 文〔= enhanced for loop〕」の導入でした。すると、SP の呪縛(反復構造)から解かれて、制御構造の抽象化やポリモフィズムの適用など、OOP の醍醐味を堪能できる環境が整います。これで、Jython/Scala などに遅れを取った Java プログラマーも、彼らと肩を並べられます。
拡張 for 文は、インターフェース Iterable に準拠する任意のクラスと組み合わせて利用できます。すると、データ構造に依存しない抽象表現が可能になるので、コードが簡潔で見通しも良くなります。
□ 情報隠蔽の原則
ソースコードに行番号を付加するときには、テキストファイルの内容を1行ずつ処理します。たとえば、次のように
for (String line: new TextStream(name)) { ...
指定した名前 name のファイルの各行 line を参照できます。
このとき、TextStream を利用するプログラマーは、各行を読み込む手段や、ファイルが存在しないときの例外処理などの詳細を知りませんし、知る必要もありません。というのも、その情報は「情報隠蔽の原則」に沿って、TextStream を提供するプログラマーだけが知っていいからです。
□ インターフェース java.util.Iterable
インターフェース Iterable に準拠するメソッドを再定義すると、拡張 for 文を介して「オブジェクトに最適な制御構造」を利用できます。たとえば、拡張 for 文の対象に、Iterable に準拠しないものを指定すると、
_Tips.java:118: foreach は式のタイプに使用できません。 for (String e: new StringTokenizer("This is a pen.")) { ^
コンパイラーがこれを拒否します。そこで、StringTokenizer をインターフェース Iterable に準拠させて、
for (String e: new ExTokenizer("This is a pen.")) { System.out.println(e); }
拡張 for 文を利用すると、次の結果が得られます。
$ java apple.pie._Tips This is a pen. $
 ̄これは、次のように実現します。
class ExTokenizer extends StringTokenizer implements Iterable{ public ExTokenizer(String str) { super(str); } public Iterator iterator() { return new Iterator () { public boolean hasNext() { return hasMoreTokens(); } public String next() { return nextToken(); } public void remove() {} }; } }
ここでは、インターフェース Iterable に準拠するメソッド
と(必要に応じて)インターフェース Iterator に準拠するメソッド群
- public boolean hasNext()
- public T next()
- public void remove()
を再定義します。
↑ TOP