はじめに
匿名クラスは英語では「anonymous classes」という。
今回はJavaの匿名クラスについて見ていく。
匿名クラスとは何かについてと、実際にコードを作ってみて出来ることを簡単にまとまる。
クラスについては以下参照。
クラスとオブジェクト、メソッドについてもう一度考えてみた by Javaプログラミング初心者 Vol.33
匿名クラスとは?
匿名クラスとはクラス名を持たないインナークラスのこと。
名前を持たないためオブジェクトを作成することはできず、匿名クラスを使用するにはほかのクラス内で定義する必要がある。
そのため、匿名内部クラス(もしくは匿名インナークラス)と呼ばれたりすることもある。
オブジェクトの作成方法は以下参照。
自作したクラスに状態を表すデータを作る-オブジェクトの作成方法 by Javaプログラミング初心者 Vol.37
使用する際には1つの式で匿名クラスの宣言とオブジェクトの作成を行わなければいけない。
匿名クラスはすでに存在しているクラスを拡張するか、1つだけinterfaceを使用してオブジェクトを作成するという方法がある。
interfaceについては以下の記事参照。
【Javaプログラミング】interface(インターフェース)とは?-プロショvol.57
匿名クラスの宣言方法
クラスを拡張する構文
最後の「;」を忘れないように。
interfaceを使用する構文
インターフェースのときは()内は必ず空欄になる。
匿名クラスのポイント
匿名クラスで忘れてはならないのが「1つの式で匿名クラスの宣言とオブジェクトの作成」しなければならないということ。
よって、最後に「;」をつけて1つの式であると表示する。
すでに存在しているクラスを拡張した匿名クラス
すでに存在しているクラスを拡張した匿名クラスとはどういうものか?
作ってみたコードが以下のもの。
void say() {
System.out.println(“早く起きなさい!”);
}
public static void main(String[] args) {Mother haha = new Mother() {
@Override
void say() {
System.out.println(“おはよう”);
}
};
haha.say();
}
}
実行すると以下が表示される。
オレンジ色の部分が「Motherクラス」を拡張して作成した匿名クラス。
すでにMotherクラスが存在している。
本来、Motherクラスのオブジェクトを作るなら「Mother haha = new Mother();」となる。
だが匿名クラスは既に存在するクラスを拡張してオブジェクトが作成される。
()の後ろに「;」ではなくて「{}」が続けて書かれてる。
拡張された{}の中身は「@Override void say() { System.out.println(“おはよう”); }」と書かれている。
Motherクラスに直接書かれた「sayメソッド」は「早く起きなさい!」と表示させるようになっている。
System.out.println(“早く起きなさい!”);
}
それに対して匿名クラスのメソッドは「おはよう」と表示するようになっている。
System.out.println(“おはよう”);
}
「haha」という匿名クラスのオブジェクト名を使用することで、匿名クラスに書かれたsayメソッドの「おはよう」が表示されることになる。
ワンポイント
オブジェクトはメインメソッド内でいくつでも作成することができる。
void say() {
System.out.println(“早く起きなさい!”);
}
public static void main(String[] args) {Mother haha = new Mother() {
@Override
void say() {
System.out.println(“おはよう”);
}
};Mother okasan = new Mother();haha.say();okasan.say();}
}
水色部分がMotherクラスから作成したオブジェクト(名前はokasan)とメソッド名を指定したもの。
匿名クラスを含まないオブジェクトを作成すれば、「早く起きなさい!」を表示させることもできる。
いつも通りのオブジェクトを作成する手順。
色々自分で試してみるのがオススメ。
interfaceを使用した匿名クラス
上で使ったコードを一部編集してinterfaceを使用して匿名クラスを作ってみた。
void say() ;
}public class Mother {
public static void main(String[] args) {Mother haha = new Mother() {
@Override
void say() {
System.out.println(“こんにちは”);
}
};
haha.say();}}
実行すると以下が表示される。
同じくオレンジ部分が匿名クラス。
interfaceクラスの中に書かれたメソッドは中身は空っぽでなくてはならない。
その中身を匿名クラスで記述している(void say() {System.out.println(“こんにちは”);})といった形。
@Override
@Overrideは実際なくてもプログラムは実行される。
だが、とても重要な役割を果たすから絶対に書いたほうがいい。
overrideは日本語訳に直すと「上書き」という意味がある。
Javaで使用する際は大文字の「O」から始めて書く。
日本語訳と同じく、すでにあるデータを上書きする役割がある。
@Overrideの役割の確認
以下のコードは一番上で扱ったMotherクラスから抜粋したコード。
System.out.println(“早く起きなさい!”);
}
sayメソッドには「早く起きなさい!」と表示させるプログラムが書かれている。
そして以下が匿名クラスから抜粋したコード。
void say() {
System.out.println(“おはよう”);
}
すでにMotherクラス直下には「早く起きなさい!」と表示させるsayメソッドが書かれている。
だが匿名クラスで同じメソッド名を使用して新しい処理内容(「おはよう」)を与えることで、データが上書きされる。
実際に実行すると、「おはよう」が表示された。
上書きされる条件は同じ名前をもつということ。
@Overrideの重要性
「早く起きなさい!」のsayメソッドを上書きして「おはよう」に変えたい。
「@Override」がなければ、もし匿名クラスのメソッド名を書き間違えていたら、書き間違えたものは新しいメソッド名として認識されてしまう。
例えば「@Override」がない以下のコード。
void say() {
System.out.println(“早く起きなさい!”);}
public static void main(String[] args) {Mother haha = new Mother() {
void sad() {
System.out.println(“こんにちは”);
}};
haha.say();}}
Motherクラス直下にはsayメソッドが書かれているのに、匿名クラスの中にはsadと書き間違ってしまったメソッド名がある。
けれども@Overrideがないから、sadという名前のメソッドは書き間違えではなく新しいメソッド名だとコンピュータが誤解してしまった。
だからsadになっていてもエラーが出ない。
匿名クラスに書かれた@Overrideは、大本のクラス(今回の場合はMotherクラス)に一致するものがあるかどうかを探してくれる。
もし一致するものが無ければエラー表示になる。
「@Override」を書かずにメソッド名を間違えてしまったら、短いプログラムなら自分で気づくかもしれない。
だがコードが長くなると、もし入力を間違えてしまったときにエラーが出ないため間違いに気づかない恐れがある。
@の機能
「@」は「注釈」を宣言するためのもの。
プログラムを実行すると、注釈を使用してコードを検査し、エラーを検出したりしてくれる。
@を使った注釈は他にもあるが、その中でも今回の「@Override」は重要なもの。
最後に
今までとオブジェクトの作り方がちょっと違うから、間違えそう・・・。
@Overrideだけ忘れずに書くことだけは気を付けようと思う。
また整理できたときにほかの「@」がつくコードをまとめることにする。
コメント