新人SEの学習記録

14年度入社SEの学習記録用に始めたブログです。もう新人じゃないかも…

学習記録:ネストクラス

[Java] Javaの学習

内容: 6章 ネストクラス

1)内部クラス
public class Hoge {
    int huga;
    private class Nyoro {
        pulic Nyoro() {
        ...
        }
    }
}
  • JDK内では一般的、特にコレクションでよく使われる
  • 内部クラス自体はそのクラスの1メンバと言える
    • 外部クラスの全てのメンバにアクセス可能
  • 合成をモデル化するのに最も良く使用される
    • 合成:集約される側のライフサイクルが、集約を実行するオブジェクトの制御下にある
    • 内部クラスはprivate, protectedを推奨
2)限定スコープ内部クラス
public class Hoge {
    public someMethod() {
        class Nyoro {
        ...
        }
        Nyoro n = new Nyoro();
    }
}
  • メソッド内や、中括弧で囲ったブロック内で宣言される内部クラス
  • 宣言以降は通常のクラスと同様に使用可
  • それを宣言するブロックのfinal変数と、外部クラスの全てのメンバにアクセス可能

※無名クラス

hoge.addSomeClass(new ParentClass() {
    public void someMethod() {
        ...
    }
});
  • 一度しか使用できない
  • メソッドのパラメータとして使用するか、変数に割り当てる必要
  • 上位型のクラスの拡張orインタフェースを実装したクラスになる
  • 書式
    • 上位型のクラス/インタフェース名で始まる(上の例だとParentClass)
    • 次に上位型のコンストラクタの引数(上の例だと()=空)
    • abstractやfinalは不可
    • コンストラクタは配置不可(無名なので)
  • 問題点
3)staticネストクラス
public class Hoge {
    public static class Huga {
        public void someMethod() {
        ...
        }
    }
}
  • staticキーワードで宣言されるネストクラス
  • 外部クラスのstaticメンバにのみアクセス可能
その他の内部クラス・インタフェース
  • 二重ネストクラス:使うな!
  • インタフェース内のネストクラス:使うな!
  • ネストインタフェース:無意味!
まとめ
  • 日常的に使うにはおすすめしないが、挙動の理解は重要
  • 合成関係のモデル化、隠蔽したいクラスの内部動作の実装などには重宝

所感

  • 結局使いどころは難しい(というか基本的には使わないほうが良い)
  • とりあえず挙動だけはわかったのでコレクションの実装などを見てみる

追記:無名クラス使用例

  • マウスクリックのアクションリスナを無名クラスで作る
  • わざわざクラスで作るのは面倒なので
  • また、ラムダ式ならもっと簡単に書けるらしい
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;

class ClickAction implements ActionListener {

   @Override
   public void actionPerformed(ActionEvent e) {
       System.out.println("クリック!!!");
   }

}

public class FrameTest extends JFrame {

   public FrameTest() {
       setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       setSize(300, 400);
       setVisible(true);

       JButton button = new JButton("click!");
       // button.addActionListener(new ClickAction());
       button.addActionListener(new ActionListener() {

           @Override
           public void actionPerformed(ActionEvent e) {
               System.out.println("click!!!");

           }
       });

       add(button);
   }

   public static void main(String[] args) {
       new FrameTest();

   }
}