🎯

【Java】クラス解説37・内部クラス

2024/05/16に公開

ネストクラス

ネストクラスとは、クラスの中に定義されたクラスです。
ネストクラスは、以下の種類に分けられます。

  1. 内部クラス
  2. ローカルクラス
  3. 匿名クラス
  4. スタティックネステッドクラス

内部クラス

内部クラスは、外部クラスの直下で作成されたクラスであり、外部クラスと密接な関係にあります。


外部クラスから内部クラスのインスタンスを生成し内部クラスのメソッドにアクセスするコード例

public class Main {
    public static void main(String... args) {
        // 外部クラスのインスタンスを生成
        Fuzi fz = new Fuzi();
        // 外部クラスのインスタンスから use メソッドを呼び出し
        fz.use();
    }
}

class Fuzi {
    // 内部クラスを定義
    class Sakura {
        // printName メソッドを定義
        void printName() {
            System.out.println("サクラ");
        }
    }

    void use() {
        // 外部クラスから内部クラスのインスタンスを生成
        Sakura sk = new Sakura();
        // 外部クラスから内部クラスの printName メソッドを呼び出し
        sk.printName();
    }
}

出力結果

サクラ

外部クラスより外から内部クラスのインスタンスを生成し内部クラスのメソッドにアクセスするコード例

public class Main {
    public static void main(String... args) {
        // 外部クラスをインスタンス化する
        Fuzi fz = new Fuzi();
        // 外部クラスより外から内部クラスをインスタンス化
        Fuzi.Sakura sk = fz.new Sakura();

        // 外部クラスより外から内部クラスのメソッドを呼び出す
        sk.printName();
    }
}

class Fuzi {
    // 内部クラス
    class Sakura {
        // printName メソッド
        void printName() {
            System.out.println("サクラ");
        }
    }
}

出力結果

サクラ

内部クラスから外部クラスの private なフィールドにアクセスするコード例

public class Main {
    public static void main(String... args) {
        // 外部クラスをインスタンス化する
        Fuzi fz = new Fuzi();
        // 外部クラスより外から内部クラスをインスタンス化
        Fuzi.Sakura sk = fz.new Sakura();
        
        // // 内部クラスのインスタンス化(省略バージョン)
        // Fuzi.Sakura sk = new Fuzi().new Sakura();

        // 外部クラスより外から内部クラスのメソッドを呼び出す
        sk.printName();
    }
}

class Fuzi {
    // 外部クラスの private なフィールド
    private String name = "サクラ";
    
    // 内部クラス
    class Sakura {
        // printName メソッド
        void printName() {
            // 内部クラスから外部クラスの private なフィールドにアクセス
            System.out.println(name);
        }
    }
}

出力結果

サクラ

内部クラスから外部クラスの private なメソッドにアクセスするコード例

public class Main {
    public static void main(String... args) {
        // 外部クラスをインスタンス化する
        Fuzi fz = new Fuzi();
        // 外部クラスより外から内部クラスをインスタンス化
        Fuzi.Sakura sk = fz.new Sakura();
        // 外部クラスより外から内部クラスのメソッドを呼び出す
        sk.nameBloom();
    }
}

class Fuzi {
    // 外部クラスの private なフィールド
    private String name = "サクラ";
    
    // 外部クラスの private なメソッド
    private void bloom() {
        System.out.println(name + "が咲く");
    }
    
    // 内部クラス
    class Sakura {
        // 内部クラスのメソッド
        void nameBloom() {
            // 外部クラスの bloom メソッドを呼び出す
            bloom();
        }
    }
}

出力結果

サクラが咲く

シャドーイングのコード例

シャドーイングとは、内部クラスの変数等が、外部クラスの変数等と同じ名前の場合、外部クラスの変数等が隠されることを言います。
そのため、外部クラスの変数等にアクセスするには、明示的に行う必要があります。

public class Main {
    public static void main(String... args) {
        // 外部クラスをインスタンス化する
        Fuzi fz = new Fuzi();
        // 外部クラスより外から内部クラスをインスタンス化
        Fuzi.Sakura sk = fz.new Sakura();
        // 外部クラスより外から内部クラスのメソッドを呼び出す
        sk.printName();
    }
}

class Fuzi {
    // 外部クラスの private なフィールド
    private String name = "フジ";
    
    // 内部クラス
    class Sakura {
        // 外部クラスと同名の name を定義
        private String name = "サクラ";
        
        // printName メソッド
        void printName() {
            // シャドーイング
            System.out.println(name);
            // 明示的に外部クラスの変数にアクセス
            System.out.println(Fuzi.this.name);
        }
    }
}

出力結果

サクラ
フジ

Discussion