はじめに
Javaの学習を始めたのでアウトプットとして投稿しています
今回は内部クラスについてまとめました
内部クラスとは?
名前の通りクラスの中にクラスがあり、ネストしているような状態のクラスのこと
通常は1ファイルの中に1クラスを定義するが、言語仕様上は1ファイルの中にいくつもクラスを持つことが出来る
クラスAの中に内部クラスB、の中に内部クラスCを持つ
public class A {
public class B {
public class C {
}
}
}
これは1ファイルに複数のクラスを持っているだけで内部クラスではない
public class A {
}
class B {
}
使い方
クラス同様インスタンス化ができるが制約もある
- staticクラスは、クラス外から直接インスタンス化できる
- 非staticクラスは、外部クラスのインスタンスからのみインスタンス化できる
(非staticな場合のみ内部クラスと呼ぶ、それ以外は「ネストしたクラス」として扱う場合あり)
具体例
非staticな内部クラス
public class Outer {
public class Inner {
}
}
別のクラス(クラスCと仮定)から↑をインスタンス化
public class Example {
public static void main(String[] args) {
Outer outer = new Outer();
// クラスOuterの内部クラスInnerをインスタンス化
Outer.Inner inner = outer.new Inner();
}
}
クラスCからクラスInnerを直接参照できないため、型として用いる際にはOuter.Inner
、もしくはimport inner_class_sample.Outer.Inner;
を記述すればInner inner = ~
で生成できる
非staticなクラスInnerをインスタンス化するには外部クラス(クラスOuter)のインスタンスを使ってインスタンスを作る必要があるため、outer.Inner();
と記述する
⚠new outer.Inner();
ではないので注意
staticな内部クラス
public class Outer {
public static class Inner {
}
}
インスタンス化
public class Example {
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner inner = new OuterInner();
}
}
new Outer.Inner();
で直接インスタンス化が可能
先程と同様、import文があればnew Inner();
でok
内部クラスと外部クラスの関係性
内部クラスは外部クラスのフィールドを直接参照できる
public class Outer {
private String greeting = "こんちは";
public class Inner {
public String hello() {
// "こんちは"が返る
return greeting;
}
}
}
たとえprivate
でも内側からであれば参照可能
ただし内部クラスがstaticだと非staticのgreeting
は参照できない
→private static
フィールドがstaticなら参照可能
内部クラスを使うケース
1ファイル1クラスを破ってまで使用するならメリットが大きい場合に限って使用
- 定数クラスを読みやすくしたい時
定数クラス:定数をまとめて置いとくクラスの事
猫の名前、猫の足の本数、タコの名前、タコの足の本数を定数化すると仮定
一つの定数クラスの中に全ての定数を置くだけだと、全く相互関係がない猫の定数とタコの定数があるのは読みにくくなる
そのため定数クラスの中でpublic static class Cat
とpublic static class Octopus
を作成し、その中に定数を定義する
// 定数クラス
public class Constants {
//内部クラスCatの中に、猫関係の定数を定義
public static class Cat {
public static final String NAME = "猫";
public static final int LEG_COUNT = 4;
}
//内部クラスOctopusの中に、タコ関係の定数を定義
public static class Octopus {
public static final String NAME = "タコ";
public static final int LEG_COUNT = 8;
}
}
使用例)Constants.Cat.NAME
で猫の名前の定数が取得できる
- クラス間の関連性を強調したい時
猫クラス、猫の爪クラス、タコクラス、タコの吸盤クラス
Catクラスの中にCatNailクラスを、Octopusクラスの中にOctopusSuckerクラスを内部クラスにすることで、関連性が表現できる
しかし詰め込みすぎると可読性・メンテナンス性が落ちるので使いたい時は注意する
最後に
結局使い所がいまいちわかりませんでしたが、とりあえず頭の片隅に入れておこうと思います。
閲覧頂きありがとうございました。