[Java] ネストしたクラスについてのまとめ

クラス内に定義するクラスを総称してネストしたクラスと呼び、外側のクラスをエンクロージングクラスと呼びます。

ネストしたクラスには次の種類があります。

  1. インナークラス
  2. staticインナークラス
  3. 匿名クラス
  4. ローカルクラス

インナークラス

インスタンス化

new エンクロージングクラス().new インナークラス()
  • インナークラスのインスタンス化するには、エンクロージングクラスのインスタンスを先に生成する必要がある。

定義例

public class InnerTest {
    private class Test {
        private void method() {
            System.out.println("Test.method");
        }
    }

    public static void main(String[] args) {
        new InnerTest().new Test().method();
    }
}
  • インナークラス、およびそのメソッドのアクセス修飾子はpublic、protected、private、無しの4つとも指定できる。
  • privateを指定してもエンクロージングクラスからは呼び出すことができる。

実行結果

java InnerTest.java
Test.method

staticインナークラス

インスタンス化

new インナークラス()
  • staticインナークラスのインスタンス化には、エンクロージングクラスのインスタンスは必要ない。
  • staticインナークラスが外部のクラスファイルの場合は、「new エンクロージングクラス.インナークラス()」のように生成する。

定義例

public class InnerTest {
    private static class Test {
        private void method() {
            System.out.println("Test.method");
        }
    }

    public static void main(String[] args) {
        new Test().method();
    }
}

実行結果

java InnerTest.java
Test.method

匿名クラス

匿名クラスはインターフェースを実装したクラス、抽象クラスを継承したサブクラス、具象クラスを継承したサブクラスとして名前のないクラスを宣言し、クラスの実装内容のみをその場で定義することができる。

定義例

interface Itest {
    public void doTest();
}

public class AnonymousTest {
    public static void main(String[] args) {
        Itest itest = new Itest() {
            @Override
            public void doTest() {
                System.out.print("Itest.doTest");
            }
        };
        
        itest.doTest();
    }
}
  • 匿名クラスは名前の無いクラスなのでコンストラクタは定義できません。初期化したい場合はコンストラクタの代わりに初期化子「{}」を使用する。

実行結果

java AnonymousTest.java
test.doTest

ローカルクラス

ローカルクラスはメソッド内に定義されるクラスで、利用可能な範囲も定義されたメソッド内に絞られる。

定義例

public class LocalTest {
    public static void main(String[] args) {
        String localVar = "Hello";

        class Test {
            private void doTest(String str) {
                System.out.print(localVar + str);
            }
        }

        Test test = new Test();
        test.doTest(" Test");
    }
}
  • ローカルクラス内でメソッド内に定義されたローカル変数を使用することが出来る。ただし以下の制限があり、守られていない場合はコンパイルエラーになる。
    1. ローカルクラスの定義よりも前に定義されていなくてはならない。
    2. final、もしくは実質的なfinalである必要がある。実質的なfinalとは変数の定義後、一度も変更されていないこと。

実行結果

java LocalTest.java
Hello Test

コメント

このブログの人気の投稿

docker-compose up で proxyconnect tcp: dial tcp: lookup proxy.example.com: no such host

docker-compose で起動したweb、MySQLに接続できない事象

【PHP】PHP_CodeSnifferを使う(コーディングルールのカスタマイズ)