未来エンジニア養成所Blog

プログラミングを皆に楽しんでもらうための情報をお届けします。

【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