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

16内部クラス

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

内部クラス

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

概要

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

【ExInner.java】クラスExInner内に内部クラスInInnerを宣言した例です。

class ExInner {
    private String exMsg = "ExInnerクラスのメンバ変数";
    public static void main(String[] args) {
        ExInner ei = new ExInner();
        ei.exeClass();
    }

    //(1)
    private class InInner {
        private String inMsg = "InInnerクラスのメンバ変数";
        //(2)
        void inMethod() {
            System.out.println(exMsg);
            System.out.println(inMsg);
        }
    }

    //(3)
    void exeClass() {
        InInner ii = new InInner();
        ii.inMethod();
    }

}

ExInner.javaの解説

  1. (1)内部クラスInInnerを宣言します。
  2. (2)inMethodメソッドを宣言し、ExInnerクラスのメンバ変数とInInnerクラスのメンバ変数を参照しています。
  3. (3)exeClassメソッドで内部クラスInInnerのオブジェクトを生成し、inMethodメソッドを実行しています。

ExInner.javaの実行結果

C:\source>javac ExInner.java

C:\source>java ExInner
ExInnerクラスのメンバ変数
InInnerクラスのメンバ変数

C:\source>

特徴

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

無名クラス

メソッド内で内部クラスを宣言する場合、内部クラスのクラス名がない無名クラスというものがあります。無名クラスは抽象クラスやインタフェースを実装する際に使用します。

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

interface ExInter {
    void sayHello(int x);
}

//ExInterインタフェースを実装するImpExInterクラスを宣言
class ImpExInter implements ExInter{
    public void sayHello(int x) {
        //sayHelloメソッドの実装
    }
}

class HelloInter {
    public static void main(String[] args) {
        ImpExInter object1 = new ImpExInter();
        object1.sayHello(5);
    }
}

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

interface ExInter {
    void sayHello(int x);
}

class HelloInter {
    public static void main(String[] args) {

        //mainメソッド内で無名クラスを使用し、ExInterインタフェース
        //を実装
        ExInter object1 = new ExInter () {
            public void sayHello(int x) {
                //sayHelloメソッドの実装
            }
        };

        object1.sayHello(5);
    }
}

無名クラスはクラスの宣言だけでなく、オブジェクトの生成までも行います。無名クラスは以下のような使われ方をします。

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


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

無名クラスを利用することで、新たなクラスを宣言することなく、メソッド内で抽象クラス、インタフェースを実装することができます。ただ、無名クラスの利用は実装が非常にシンプルなものに止めるべきとされています。本来クラスの宣言が行われない箇所で宣言が行われており、プログラムが読みにくくなるためです。

16内部クラス