未来エンジニア養成所Blog

月単価180万以上のプログラミング講師がプログラミングを皆に楽しんでもらうための情報をお届けします。

【Java】内部クラス Part1

title


内部クラスとは

内部クラスとは、クラスの中に定義されたクラスのことを指します。

内部クラスを利用することで、クラス間の関係がわかりやすくなり、ソースコードがシンプルになり、可読性が増します。

また、使用場所を限定し、その存在を外部から隠したい場合にも使用します。


内部クラスの必要性

ここでMyObj クラスがMain以外のクラスからは使われないとします。

すると、少し不便なことが出てきます。

もし他にMyObjというクラスを作りたい場合、クラス名がすでに使われているため作成することが出来ません。

それは片方のMyObj.classによってもう片方のMyObj.classファイルが上書きされてしまうからです。

内部クラスの必要性


そのため、毎回名前を変えなければいけません。

これは不便なのでJDK1.1からは内部クラスというものが導入されました。

これは単純に、クラスの中にクラスを書くことができるというものです。


内部クラスは定義された場所によって、呼び出し方や動作が変わってきます。


ポイント!内部クラスの種類

  • ネストクラス
    staticで定義されたクラス

  • インナークラス
    static以外で定義されたクラス

    • メンバーインナークラス
      クラスのメンバとして定義されたクラス

    • ローカルインナークラス
      メソッド内で定義されたクラス

    • 無名インナークラス
      ローカルインナークラスの中で名前をつけないもの


内部クラスの中でもstaticなものを「ネストクラス」、それ以外を「インナークラス」と呼びます。


ネストクラス

ネストクラスはstaticというキーワードをつけて定義したクラスです。

外側のクラスの1つ内側に記述します。


【ネストクラスの作成】

public class NestSample{
    static class MyObj{
        public void foo( ){
            System.out.println("ネストクラスの機能が呼び出されました!");
        }
    }

    public static void main(String[ ] args){
        MyObj obj = new MyObj( );
        obj.foo( );
    }
}


実行結果

ネストクラスの機能が呼び出されました!


NestSampleクラスの内部でMyObjクラスが定義されておりNestSampleクラスから、MyObjクラスをインスタンス化してMyObjクラスのfoo()メソッドを呼び出しています。


staticとは

前までの記事で見てきたHumanクラスはstaticキーワードがついていないクラスです。

Humanクラスに所属するフィールドやメソッドを利用するには、mainメソッドからHumanクラスのインスタンスを作成し、そのインスタンスからアクセスしました。

Humanクラス


一方、staticキーワードがついたクラス、フィールド、メソッドはインスタンス内ではなく、クラスに1つだけ存在しますので、これらにアクセスするには、「クラス名.メソッド名」 「クラス名.フィールド名」と記述をします。

staticクラス


外部クラスからstaticなネストクラスを利用するには、左辺に宣言の型として

外側クラス名.ネストクラス名

と記述します。


ネストクラスのメンバにアクセスするには、ネストクラスのインスタンスを作成し、そのインスタンスからフィールドやメソッドといったメンバを呼び出します。

new 外側クラス名.ネストクラス名

ネストクラスのインスタンス名.ネストクラスのフィールド名(メソッド名)


【ネストクラスの利用】

class Outer{
    static void foo(){
        System.out.println("Outerクラスのfoo()が呼び出されました");
    }
    static class Nest{
        Nest(){
            System.out.println("Nestクラスがインスタンス化されました");
        }
    }
}

public class NestSample2{
    public static void main(String[ ] args){
        Outer.foo(); 
        Outer.Nest nest = new Outer.Nest();
    }
}


実行結果

Outerクラスのfoo()が呼び出されました
Nestクラスがインスタンス化されました


NestSample2.javaファイル内にmainメソッドのある「NestSample2」クラス、staticなネストクラス「Nest」を内部クラスとして持つ「Outer」クラスが定義されています。

main()メソッドの14行目でOuterクラスのfoo()メソッドを呼び出しています。

foo()メソッドはstaticキーワードがついているため、インスタンスを生成する必要はなく、「クラス名.メソッド名」で呼び出します。

したがってOuter.foo()と呼び出すことができます。

次に15行目では、Outerクラス内に定義されている「Nest」クラスを利用しています。

左辺の宣言の型では、Nestクラスがstaticであるため、「外側のクラス名.内側のクラス名」と指定するため、Outer.Nestと記述します。

staticなインナークラスは静的メンバであるためアウタークラスのインスタンスがなくてもアクセスができます。

したがって右辺ではOuterクラスはインスタンス化せず、Nestクラスのみをインスタンス化するため、new Outer.Nest()と指定をしています。

これによりNestクラスがインスタンス化され、6行目のコンストラクタが呼び出されることになります。



「メンバーインナークラス」「ローカルインナークラス」「無名インナークラス」については、次回の記事で解説します!


「内部クラス Part2」へ続きます

phoeducation.work


参考図書



独学で挫折しそうになったら、オンラインプログラミングスクール
未来エンジニア養成所Logo



あわせて学習したい

phoeducation.work phoeducation.work