今日は Java の内部クラスについて復習しましょう。内部クラスには通常、次のような種類があります:静的内部クラス、メンバー内部クラス、匿名内部クラス、およびメソッド内部クラスです。以下では、主に静的内部クラスとメンバー内部クラスについて説明します。
- 概要
- 静的内部クラス
- メンバー内部クラス
- 匿名内部クラスとメソッド内部クラス
- 総括
概要#
内部クラスは、クラス内で定義されるクラスです。内部クラスは独立したクラスであり、コンパイル後には独立した.class ファイルが生成されます。その名前は外部クラスのクラス名と $ 記号で始まります。内部クラスも private、default、protected、public 修飾子を使用することができます。以下は内部クラスの書き方の例です。
/**
* 内部クラス
* @author jzman
*/
public class OutterClass {
//静的内部クラス
private static class StaticInnerClass{
}
//メンバー内部クラス
private class FieldInnerClass{
}
//匿名内部クラス
Runnable runnable = new Runnable() {
@Override
public void run() {
}
};
private void method() {
//メソッド内部クラス(ローカル内部クラス)
class InnerClass{
}
}
}
静的内部クラス#
- 静的内部クラスには静的メンバーと非静的メンバーが含まれる場合があります。
- 静的内部クラスは外部クラスの静的メンバーや静的メソッドを直接呼び出すことができますが、非静的メンバーや非静的メソッドを呼び出すことはできません。
- 関連のないクラスで、静的内部クラスのオブジェクトを直接作成することができます。
- 静的内部クラスは外部クラスにほとんど依存せず、基本的には外部クラスに依存しません。
/**
* 静的内部クラスのデモンストレーション
*/
public class StaticInnerClassDemo {
public static void main(String[] args) {
//他のクラスから非プライベートな内部クラスのインスタンスを直接作成できます
OutterClass1.InnerClass innerClassB = new OutterClass1.InnerClass();
InnerClass innerClassA = new InnerClass();
innerClassA.testStaticInnerClass();
//...
}
}
//外部クラス
class OutterClass1{
//非静的メンバ変数
int ageA = 18;
//非静的メソッド
public void methodA() {
}
//静的メンバ変数
static int ageB = 18;
//静的メソッド
public static void methodB() {
}
private void methodC() {
//外部クラスから静的内部クラスのメソッドを呼び出す
InnerClass innerClass = new InnerClass();
innerClass.testStaticInnerClass();
}
//静的内部クラス
static class InnerClass{
public void testStaticInnerClass(){
//静的内部クラスは外部クラスの非静的メンバ変数やメソッドにアクセスできません
// System.out.println(ageA);
// methodA();
//静的内部クラスは外部クラスの静的メンバ変数やメソッドにアクセスできます
System.out.println(ageB);
methodB();
}
}
}
メンバー内部クラス#
- メンバー内部クラスは、外部クラスのすべてのメンバーにアクセスできます。
- メンバー内部クラスのオブジェクトの作成には、外部クラスのオブジェクトに依存する必要があります。外部クラスが存在しないと内部クラスも存在しません。
- メンバー内部クラスは外部クラスのメンバー変数です。
- メンバー内部クラスには静的メンバーは持てませんが、定数は存在することができます。
/**
* メンバー内部クラスのデモンストレーション
*/
public class FieldInnerClassDemo {
public static void main(String[] args) {
//メンバー内部クラスは外部クラスに依存するため、外部クラスを経由して内部クラスのインスタンスを直接作成することはできません
// InnerClass innerClass = new InnerClass();
//正しい方法は、他のクラスから内部クラスのインスタンスを作成することです
OutterClass2 outterClass2 = new OutterClass2();
OutterClass2.InnerClass innerClass = outterClass2.new InnerClass();
innerClass.testFieldInnerClassMethod();
}
}
//外部クラス
class OutterClass2{
//非静的メンバ変数
int ageA = 18;
//非静的メソッド
public void methodA() {
}
//静的メンバ変数
static int ageB = 18;
//静的メソッド
public static void methodB() {
}
private void methodC() {
//外部クラスからメンバー内部クラスのメソッドを呼び出す
InnerClass innerClass = new InnerClass();
innerClass.testFieldInnerClassMethod();
}
//メンバー内部クラス
class InnerClass{
//メンバー内部クラスには静的メンバーを持つことはできません
// static int a = 10;
//メンバー内部クラスには定数の形式で存在することができます
static final int b = 10;
public void testFieldInnerClassMethod(){
//メンバー内部クラスは外部クラスのすべてのメンバー変数とメソッド(静的および非静的)に直接アクセスできます
System.out.println(ageA);
methodA();
System.out.println(ageB);
methodB();
}
}
}
匿名内部クラスとメソッド内部クラス#
匿名内部クラスは名前がないため、実装はクラス本体で具体的に行われ、最終的に関連クラスの匿名オブジェクトが返されます。最終的に返されるのは匿名のインスタンスなので、匿名内部クラスの後にはセミコロンを追加する必要があります。メソッド内部クラスは通常、クラスのローカル位置に定義され、現在のコードブロックおよび外部クラスのすべての変数にアクセスできます。
総括#
クラス間のメンバー変数の相互呼び出しは、実際にはオブジェクトのメンバー変数にアクセスすることです。メンバー内部クラスが外部クラスのメンバー変数やメソッドにアクセスできるのは、内部クラスが外部クラスの参照を保持しているためです。通常、OutterClass.this を使用して外部クラスのオブジェクトを取得します。外部クラスが内部クラスのメンバー変数やメソッドにアクセスする場合も、内部クラスの参照を保持する必要があります。したがって、外部クラスが内部クラスのメンバー変数やメソッドにアクセスする場合は、まず内部クラスのオブジェクトを作成し、その後オブジェクトを使用して対応するメンバー変数やメソッドにアクセスする必要があります。