以前の記事で「通常のクラスと匿名クラスの書き方の比較を見たい」という意見があったので、少し補足を行います。
サンプルコードの通り、匿名クラスの場合、クラスに名前を付ける必要が無く、またオブジェクト生成と同時に処理を定義することができます。
これにより、以下のようなメリットがあります。
- 記述を簡潔にできる
- 使い捨てのクラスを定義でき、使い捨てであるという意図も明確にできる
- (ソースファイル名とクラス名を同じにする場合)管理が容易になる
【サンプルコード】
・AnonymousClass.java
1 2 3 4 5 6 7 8 9 |
public class AnonymousClass { private String str = "Hello Class!"; public String getStr() { return str; } public void print() { System.out.println(getStr()); } } |
・AnonymousSubClass.java
1 2 3 4 5 6 |
// 通常のクラスの定義(クラスの継承) public class AnonymousSubClass extends AnonymousClass { public void print() { System.out.println("NonAnonymous:" + getStr()); } } |
・AnonymousInterface.java
1 2 3 |
public interface AnonymousInterface { public void print(); } |
・AnonymousImplementsClass.java
1 2 3 4 5 6 |
// 通常のクラスの定義(インターフェースの実装) public class AnonymousImplementsClass implements AnonymousInterface { public void print() { System.out.println("NonAnonymous:Hello Interface!"); } } |
・AnonymousMain.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
public class AnonymousMain { public static void main(String[] args) { // 通常のクラスのオブジェクトの生成(クラスの継承) AnonymousClass nac = new AnonymousSubClass(); nac.print(); // 匿名クラスの定義とオブジェクト生成(クラスの継承) AnonymousClass ac = new AnonymousClass() { public void print() { System.out.println("Anonymous:" + getStr()); } }; ac.print(); // 通常のクラスのオブジェクトの生成(インターフェースの実装) AnonymousInterface nai = new AnonymousImplementsClass(); nai.print(); // 匿名クラスの定義とオブジェクト生成(インターフェースの実装) AnonymousInterface ai = new AnonymousInterface() { public void print() { System.out.println("Anonymous:Hello Interface!"); } }; ai.print(); } } |
【実行結果】
1 2 3 4 |
NonAnonymous:Hello Class! Anonymous:Hello Class! NonAnonymous:Hello Interface! Anonymous:Hello Interface! |
良い意見やコメントを頂いた時は、今回のような形で答えていきたいと思います!
プログラム初心者なのですが、同僚が無名クラスをよく使っており、気になって調べていました。
簡潔に記述出来ることがメリットとありますが、クラスの役割が分かりにくくなったりしないのでしょうか?
また、使い捨てとするシーンがあまり思い浮かばないのですが、なにかわかりやすい具体例はありますでしょうか?
ご質問ありがとうございます。
今回の記事の例に即して回答します。
>また、使い捨てとするシーンがあまり思い浮かばないのですが、なにかわかりやすい具体例はありますでしょうか?
こちらの質問から先に回答します。
今回の例で言うと、AnonymousClassクラスのサブクラスを一つの箇所だけで使用(オブジェクト生成)する場合に、「使い捨て」としてみなすことができます。
逆に、複数の箇所で使用する場合は「使い捨て」としてみなすことができません。
「使い捨て」としてみなせる場合、匿名クラスとしてサブクラスを定義すると、クラス名定義(クラスファイル)を省略できるため、管理が楽になります。
逆に、「使い捨て」としてみなせない場合は、匿名クラスとして定義すると、生成する度にクラス内の処理の記述(今回の例で言うとprint()メソッドの記述)が必要となり、記述が冗長になってしまいます。複数個所に同じ記述があると、改修する時に改修漏れの原因にもなります。
>簡潔に記述出来ることがメリットとありますが、クラスの役割が分かりにくくなったりしないのでしょうか?
おっしゃる通り、クラス名定義を省略するため、そのことによりクラスの役割が分かりにくくなる可能性はあります。
「使い捨て」としてみなせない場合はもちろん、「使い捨て」としてみなせる場合もクラスの役割を明示することが適切な場合はクラス名定義はするべきだと思います。