Javaに関する様々な情報をご紹介します。

16内部クラス

Javaに関する様々な情報をご紹介します。

内部クラス

クラス内に宣言されたクラスを内部クラスといいます。ここでは、内部クラスの概要・使用例及び、内部クラスのうち、クラス名を宣言しない無名クラスについて解説します。

概要

内部クラスはクラス間の関係を明確にするために使用します。あるクラスのメンバ変数やメソッドに強く依存しているクラスは、そのクラスの内部クラスとして宣言します。

【例1】Outerクラス内に内部クラスInnerを宣言した例です。

public class Outer {
  private String outerMsg = "Outerクラスのメンバ変数";

   //内部クラスInnerの宣言
   private class Inner {
    private String innerMsg = "Innerクラスのメンバ変数";
    void innerSay() {
      //内部クラスからOuterクラスのメンバ変数が参照可能
      System.out.println(outerMsg);
      System.out.println(innerMsg);
    }
  }

  void say() {
    //Outerクラスのメソッドから内部クラスのインスタンス化が可能
    Inner ins1 = new Inner();
    ins1.innerSay();
  }
}

特徴

  • 内部クラスはメンバ変数、メソッドなどと同じように、クラスの構成要素の一つです。そのため、private、protected、publicといったアクセスレベルを付与することができます。
  • 内部クラスから同じクラス内のメンバ変数、メソッドを参照することができます。メンバ変数、メソッドにprivateアクセスレベルが付与されている場合でも、同じクラス内のため参照することができます。
  • メソッド内に内部クラスを宣言することもできます。その場合、その内部クラスはメソッド内でのみ機能します。同じクラスのメンバ変数、メソッドを参照することはできません。
  • メソッド内に内部クラスを宣言した場合、内部クラスからメソッド内のローカル変数を参照することができます。ただし、参照できるローカル変数はfinal修飾子が付与されている場合のみです。

無名クラス

メソッド内で内部クラスを宣言する場合、内部クラスのクラス名がない無名クラスというものがあります。無名クラスは、宣言から、実装、インスタンス化までをまとめて一文で表現できます。普段クラスの宣言を行わない箇所で宣言するため、プログラムの可読性が落ち、メンテナンスもしにくいため非常にシンプルな実装を行う場合に使用します。

無名クラスは以下のフォーマットで利用します。クラスだけでなく、インタフェースを実装する場合にも利用できます。

new 抽象クラス型( ) { 無名クラス };


new インタフェース型( ) { 無名クラス };

無名クラスを利用した例を以下に記載します。無名クラスは通常の内部クラスで書き換えることもできます。

無名クラスを使用した場合

interface Say {
  void hello();
}

class Sample {
  void saySample() {
    //無名クラスの利用。インタフェースSayの実装とインスタンス化をまとめて実施。
    Say ins1 = new Say () {
      //インタフェースSayのhelloメソッドをオーバーライド
      @Override
      public void hello() {
        System.out.println("無名クラスです。");
      }
    };
    //helloメソッドの呼び出し
    ins1.hello();
  }
}

無名クラスを使用しない場合

interface Say {
  void hello();
}

class Sample {
  //内部クラスで、インタフェースSayの実装
  class Inner implements Say {
      //インタフェースSayのhelloメソッドをオーバーライド
      @Override
      public void hello() {
        System.out.println("内部クラスです。");
      }
  }

  void saySample() {
    //内部クラスのインスタンス化、及びhelloメソッドの呼び出し
    Inner ins1 = new Inner();
    ins1.hello();
  }
}

16内部クラス