🎯

【Java】クラス解説29・thisの使い方4

2024/01/30に公開

内部クラス

今までのクラスは、下記のように継承関係の有無はあっても、各クラスに依存関係はなく、独立したものです。

public class Main {
    public static void main(String[] args) {}
}
class MyClass {}
class Fuzi extends MyClass {}
class Sakura extends MyClass {}

内部クラスとは、下記のInクラスであり、内部クラスは外部クラスに依存します。

public class Main {
    public static void main(String[] args) {}
}
class Out {
    class In {}
}

また、内部クラスのインスタンスの生成方法は、下記のようになります。

public class Main {
    public static void main(String[] args) {
        Out outInstance = new Out();
        // 内部クラスのインスタンス生成
        Out.In inInstance = outInstance.new In();
    }
}
class Out {
    class In {}
}

内部クラスのインスタンス生成を解説すると、
外部クラス名.内部クラス名 変数名 = 外部インスタンス名.new演算子 内部クラス名()となり、

  1. 外部クラス名.内部クラス名: 内部クラスのフルクラス名です。
  2. 変数名: 内部クラスのインスタンスを格納する変数です。
  3. 外部インスタンス名.new演算子 内部クラス名(): 外部クラスのインスタンスからnew演算子を使用して内部クラスの新しいインスタンスを生成しています。

thisの使い方4

内部クラスから外部クラスのインスタンスにアクセスするためにOut.thisを使います。

「thisの使い方4」のコード例

public class Main {
    public static void main(String[] args) {
        Out outInstance = new Out(10);
        // 内部クラスのインスタンス生成
        Out.In inInstance = outInstance.new In(20);
        inInstance.inMethod(); // 出力結果 -> 10, 20
    }
}
// 外部クラス
class Out {
    private int outField;

    public Out(int outField) {
        this.outField = outField;
    }

    public void outMethod() {
        System.out.println(this.outField);
    }

    // 内部クラス
    class In {
        private int inField;

        public In(int inField) {
            this.inField = inField;
        }

        public void inMethod() {
            // 外部クラスのインスタンスにアクセスし、そこから外部クラスのメソッドにアクセス
            Out.this.outMethod();
            System.out.println(this.inField);
        }
    }
}

コード例の解説

public class Main {
    public static void main(String[] args) {
        Out outInstance = new Out(10);
        Out.In inInstance = outInstance.new In(20);
        inInstance.inMethod();
    }
}

Mainクラスで、

  1. 実引数10を渡すコンストラクタを呼び出す外部クラスのインスタンスを生成します。
  2. 実引数20を渡すコンストラクタを呼び出す内部クラスのインスタンスを生成します。
  3. 内部クラスのインスタンスから内部クラスのメソッドを呼び出す。

class Out {
    private int outField;

    public Out(int outField) {
        this.outField = outField;
    }

    public void outMethod() {
        System.out.println(this.outField);
    }

外部クラスで、

  1. インスタンス変数outFieldを定義します。
  2. 仮引数10を受け取るコンストラクタを定義し、
  3. インスタンス変数に仮引数10を代入します。
  4. outMethodメソッドを定義して、
  5. 処理内容は外部クラスのインスタンス変数を標準出力に出力します。

    class In {
        private int inField;

        public In(int inField) {
            this.inField = inField;
        }

        public void inMethod() {
            // 外部クラスのインスタンスにアクセスし、そこから外部クラスのメソッドにアクセス
            Out.this.outMethod();
            System.out.println(this.inField);
        }
    }
}

内部クラスで、

  1. インスタンス変数inFieldを定義します。
  2. 仮引数20を受け取るコンストラクタを定義し、
  3. インスタンス変数に仮引数20を代入します。
  4. inMethodメソッドを定義して、
  5. 処理内容1は、Out.thisにより内部クラスから外部クラスのインスタンスにアクセスし、そこから外部クラスのoutMethodメソッドを呼び出します。
  6. 処理内容2は、内部クラスのインスタンス変数を標準出力に出力します。

メソッドの呼び出しと実行の流れ

MainクラスのinInstance.inMethod();から始まるメソッドの呼び出しと実行の流れは下記の通りです。

Discussion