【Java】ネストされたクラスの概念整理してみた (original) (raw)
Javaの勉強をしていて、ネストされたクラスについてイマイチちゃんと理解していないなと思ったので整理してみた。
ネストされたクラス
通常のクラス内で定義されるクラスのこと。 それぞれの概念間の包括イメージは以下の通り。
非静的な内部クラス
静的なクラスとの対比で、static修飾子をつけることができない通常のクラス内に定義されるクラス。
内部クラス
通常のクラスに内に定義されるクラス。
クラスの外側のクラス(エンクロージングクラス)のメンバにアクセスすることができる。
エンクロージングクラスをインスタンス化しないとインスタンス化することができない。
匿名クラス
インターフェースの実装クラスを事前に(class classNameのように)定義せず、呼び出し時に定義して利用するためのクラス。
ローカルクラス
メソッド内に定義されるクラス。
静的なクラス
通常のクラス内に定義されるクラスで、static修飾子がつけられたクラスのこと。
エンクロージングクラスのstatic修飾子がついたメンバにアクセスすることができる。
エンクロージングクラスをインスタンス化せずに、個別にインスタンス化することができる。
コード例
各クラスを定義して、それぞれのクラス内で定義した変数をmainメソッドから呼び出してみた例を以下に記載する。
public interface Anonymous { public String getClassName(); }
public class Normal { String className1 = "Normal";
public String getClassName() {
return this.className1;
}
public class Inner{
String className2 = "Inner";
public String getClassName() {
return this.className2;
}
public String getOuterClassName() {
return className1;
}
}
public String getLocalClass() {
class LocalClass{
String className4 = "Local";
public String getClassName() {
return this.className4;
}
}
LocalClass local = new LocalClass();
return local.getClassName();
}
public static class Static{
String className5 = "Static";
public String getClassName() {
return this.className5;
}
}
public static void main(String[] args) {
Normal normalClass = new Normal();
System.out.println(normalClass.getClassName());
Inner innerClass = normalClass.new Inner();
System.out.println(innerClass.getClassName());
Anonymous anonymousClass = new Anonymous() {
String className3 = "Anonymous";
public String getClassName() {
return this.className3;
}
};
System.out.println(anonymousClass.getClassName());
System.out.println(normalClass.getLocalClass());
Static staticClass = new Static();
System.out.println(staticClass.getClassName());
}
}
おわりに
この調査、整理するまで静的な内部クラス(staticインナークラス)の理解が難しかった。
staticなのにインスタンス化ができるってどういうこと?みたいな感じだった。
整理して考えてみたことで、static変数やstaticフィールドのように、staticのついたインナークラスは、それが定義してあるクラス(エンクロージングクラス)がインスタンス化されていなくても利用できるという風に理解することができた。