本記事では、『Oracle Certified Java Programmer, Gold SE 11』の出題範囲、『クラスとインターフェース』について、黒本の内容を自分なりに解釈し、まとめていきます
対象者としては、以下の方を想定しています
- Java SE11 Goldの試験を受ける予定で、クラスとインターフェースの項目の理解を深めたい方
- Java SE11 Goldの範囲内で、クラスとインターフェースについて、おさらいしたい方
『Java SE8 Gold』の情報が多い中、『Java SE11 Gold』の内容があまり存在しないため、本記事を作成いたしました
また、このような記事を書いているものの、『Java SE11 Gold』取得に向けて勉強している身のため、その点はご容赦ください
ネストしたクラス
以下のように、クラスの中にクラスを定義することができる
public class Hoge {
class Fuga {
}
}
これを『ネストしたクラス』と呼び、以下4つの種類が存在する
名前 | 概要 |
インナークラス | クラスの中に定義したクラス |
staticインナークラス | staticで修飾したインナークラス |
ローカルクラス | メソッド内で定義したクラス 他のメソッドから利用不可 |
匿名クラス | 様々なクラスのサブクラスとして、実装内容を定義する名前の無いクラス (詳細はこちら) |
情報隠蔽の例
情報隠蔽の例として、以下のように「private」で修飾することで、同じパッケージであっても「Fugaクラス」は「Hogeクラス」以外からはアクセスできない
public class Hoge {
private class Fuga {
}
}
インナークラスのインスタンス生成
インナークラスのインスタンスを生成するには、まず「エンクロージングクラス」のインスタンスを生成する。生成後にそのインスタンスを参照し、「インナークラス」のインスタンスを生成する
public class Hoge {
public static void main(String[] args) {
Fuga fuga = new Hoge().new Fuga();
// または
Hoge hoge = new Hoge();
Fuga fuga2 = hoge.new Fuga();
}
private class Fuga {
}
}
staticインナークラスのインスタンス生成
「インナークラス」を「staticインナークラス」にすることで、「エンクロージングクラス」のインスタンスを生成しなくても、インナークラスのインスタンス化ができる
public class Hoge {
public static void main(String[] args) {
Fuga fuga = new Fuga();
}
private static class Fuga {
}
}
ローカルクラス
「インナークラス」や「staticインナークラス」は「エンクロージングクラス」のすべてのメソッドから使用可能だが、特定メソッドからのみ使用可能にしたものが『ローカルクラス』
public class Hoge {
private void hogehoge {
class Fuga {
}
}
}
ローカル変数
「ローカルクラス」が参照するローカル変数は以下のルールに則る必要がある
- ローカルクラスの定義の前に宣言されていなければならない
- 値を変更してはならない
匿名クラス
インターフェースを実現したクラス、抽象クラスか具象クラスを継承したサブクラスとして、そのクラスの実装内容だけを定義したものを『匿名クラス』と呼ぶ
以下は、「Fugaクラス」を匿名クラスでオーバーライドした例
public class Hoge {
public static void main(String[] args) {
// 以下の「new Fuga()」後の「{}」内が匿名クラス
Fuga fuga = new Fuga() {
@Override
public void print() {
System.out.println("Hoge");
}
};
fuga.print();
}
}
public class Fuga {
public void print() {
System.out.println("Fuga");
}
}
Hoge
メソッドを追加した例
上記の例では、オーバーライドだったが、「var」で型推論することで、メソッドを追加することもできる
public class Hoge {
public static void main(String[] args) {
// 以下の「new Fuga()」後の「{}」内が匿名クラス
Fuga fuga = new Fuga() {
public void print2() {
System.out.println("Hoge");
}
};
// 元のメソッドを実行
fuga.print();
// 追加したメソッドを実行
fuga.print2();
}
}
public class Fuga {
public void print() {
System.out.println("Fuga");
}
}
Fuga
Hoge
コンストラクタ
匿名クラスでは、コンストラクタは定義できないが、初期化子「{}」 を使うことで初期化できる
public class Hoge {
public static void main(String[] args) {
// 以下の「new Fuga()」後の「{}」内が匿名クラス
Fuga fuga = new Fuga() {
{
super.print();
}
};
}
}
public class Fuga {
public void print() {
System.out.println("Fuga");
}
}
Fuga
インターフェース
staticメソッド
インターフェースのstaticメソッドは継承して使用したり、オーバーライドすることはできない
public interface Hoge {
static void print() {
System.out.println("Hoge")
}
}
public class Fuga implements Hoge {
public static void main(String[] args) {
// コンパイルエラー
print();
}
// コンパイルエラー
@Override
public static void print() {
System.out.println("Fuga");
}
}
コンパイルエラー
上記の例では「print();」では実行できないが、「Hoge.print()」であれば実行できる
デフォルトメソッド
インターフェースのデフォルトメソッドをオーバーライドしたときに、オーバーライドした側のメソッドからデフォルトメソッドを呼び出すことができる
public interface Hoge {
default void print() {
System.out.println("Hoge")
}
}
public class Fuga implements Hoge {
public static void main(String[] args) {
new Fuga().print();
}
@Override
public static void print() {
Hoge.super.print();
}
}
Hoge
privateメソッド
インターフェースにprivate修飾子で修飾した『privateメソッド』を追加できる
デフォルトメソッド内で使用する想定でprivateメソッドを追加する
public interface Hoge {
private void hoge() {
System.out.println("Hoge");
}
default void print() {
hoge();
}
}
public class Fuga implements Hoge {
public static void main(String[] args) {
new Fuga().print();
}
@Override
public static void print() {
Hoge.super.print();
}
}
Hoge
おわりに
自分のアウトプットも兼ねて、Java SE11 Goldの試験で出題される、クラスとインターフェースについてまとめました
間違っている点があった場合は、教えてくださると助かります
他の章についてもまとめていきますので、お待ちいただければと思います