「匿名クラスという、またよくわからないクラスが出てきた」
「匿名クラスがどのようなものなのか理解できない」
このようなお悩みを抱えている方は多いのではないでしょうか?
匿名クラスは初めて勉強する方にとっては少しとっつきにくいものとなっているかと思います。
私も初めて勉強した際には今までの常識を覆すものとなっていたため、理解するのに少し時間を要しました。
そんな匿名クラスに関して、初心者の方でも理解できるように自分なりに噛みください解説していきたいと思います。
匿名クラスとは?
では匿名クラスがどのようなものかと言いますと、ざっくり言うとメソッド内で定義した名前のないクラスの事です。
「え?メソッド内にクラスって定義できるの?」
「名前のないクラスってどういうこと?」
このようにたくさんの疑問が出てくるかと思いますが、一つずつ解説していきますので焦らないでください。
以前の下記記事で匿名クラスに関して少し解説したかと思います。
【Java】ラムダ式とは何なのか? | エンジニアKISARAGIの備忘録 (kisaragi-it.com)
その際に使用したコードを流用して解説していきます。
public interface Anonymous {
public String charconcat(String greeting,String name);
}
public class TimeGreet {
public static void main(String[] args) {
Anonymous ano = new Anonymous() {
@Override
public String charconcat(String greeting,String name) {
return greeting + name + "さん。";
}
};
System.out.println(ano.charconcat("おはようございます、", "斎藤"));
System.out.println(ano.charconcat("こんにちは、", "斎藤"));
System.out.println(ano.charconcat("こんばんは、", "斎藤"));
}
}
上記コードを見ていただいたら分かるかと思いますが、通常インタフェースをインスタンス化することはできません。
ですがmainメソッド内でnewでインスタンス化しているように見えます。
しかしこれはAnonymousインタフェースをインスタンス化しているわけでなく、名前のないクラスをインスタンス化していると考えることができます。
これにより、匿名クラス内にあるcharconcatも利用できるようになります。
ではなぜこんなよくわからないクラスが用意されているかと言いますと、特定メソッドでは使用するが、それ以外のクラスで再度使用することがない場合に使うことができるようにするためです。
因みにですが、匿名クラス内ではコンストラクタを定義することはできません。
理由としては、単純にコンストラクトはクラス名と同様の名前を使用するので、匿名クラスですと名前がないので定義できないという理由です。
では初期化はどのように実施するかと言いますと、初期化子という{}を使用します。
この中に初期化したい変数に値を代入することで初期化することができます。
ローカルクラスとは?
ここまで匿名クラスについて解説してきましたが、メソッド内に定義するクラスがもう一つ存在します。
それがローカルクラスです。
匿名クラスとの明確な違いとして、名前があるクラスであるということです。
使用方法として下記のようになります。
【コード例】
public class Local1 {
public void town(String city) {
class City{
public void townandcity() {
if(city == "KANAGAWA") {
System.out.println("神奈川県の県庁所在地は横浜です");
}
else if(city == "ISHIKAWA"){
System.out.println("石川県の県庁所在地は金沢です");
}
else if(city == "AICHI") {
System.out.println("愛知県の県庁所在地は名古屋です");
}
else {
System.out.println(city+"のデータが存在しません");
}
}
}
new City().townandcity();
}
}
public class LocalMain {
public static void main(String[] args) {
Local1 local=new Local1();
local.town("AICHI");
}
}
【実行結果】
愛知県の県庁所在地は名古屋です
上記は特定の県名を入力するとその県庁所在地を教えてくれるプログラムです。
見ていただいたら分かるかと思いますが、メソッド内にクラスが入っていることが分かります。
メインメソッドでLocal1をインスタンス化し、その中にあるメソッドtownに文字列を渡しています。
これだけではその中にあるローカルクラスまではたどり着くことはできません。
ではどうするのかというとLocal1クラスでローカルクラスであるCityをインスタンス化します。
これでローカルクラスにもアクセスできるようになるため、ローカルクラス内のメソッドの処理を実行することができます。
ローカルクラスは名前からもわかる通り、ローカル変数同様ローカルクラスを内包しているクラスからしかアクセスすることができません。
そしてローカルクラスからアクセスするローカル変数は実質的にfinalでなければならないという制約があります。
例えば下記のように変数city2を作成して中にAOMORIという文字列を代入したとします。
これをローカル変数内から「city2=city」でcity2の中身を書き換えようとするとコンパイルエラーが発生します。
public class Local1 {
public void town(String city) {
String city2="AOMORI";
class City{
public void townandcity() {
if(city == "KANAGAWA") {
city2=city;
System.out.println("神奈川県の県庁所在地は横浜です");
}
・・・
このようにローカル変数の値を変更することはできないので気を付けてください。
まとめ
この記事ではJavaの匿名クラスとローカルクラスに関して解説してきました。
- 匿名クラスとは?
- ローカルクラスとは?
メソッド内でクラスを使用する方法として匿名クラスとローカルクラスという2つの方法があることを紹介しました。
今までクラス内にメソッドを定義して、メソッド内では変数などを定義するということが頭に刷り込まれていたため、メソッド内にクラスを定義するというのには何とも違和感を感じるかもしれません。
何度か使用していたらそういった違和感も少しずつなくなっていくと思いますので、ぜひ積極的に使用して見てください。
以上で今回の解説は終了となります。
コメント