inner classを使う(匿名インナークラス)



インナークラスには、メソッドのコードブロックの中に記述される、ローカルインナークラスがあります。
ローカルインナークラスにはクラス名を持たない、匿名インナークラスを作る事が可能です。
下のコードは匿名インナークラスのサンプルです。


import  java.awt.event.*;
import  javax.swing.*;

public  class ExamInner2  extends  JFrame  {

    public static  void  main(String args[])  {
        ExamInner2  ei2   =   new ExamInner2();
        ei2.pack();
        ei2.setVisible(true);
    }
    ExamInner2() {
        super("ExamInner2");
        addWindowListener(
            new WindowAdapter()  {
                public  void  windowClosing(WindowEvent  we)  {
                    System.exit(0);
  
                }
            }
         );

        JButton  jb  = new  JButton("click");
        jb.addActionListener( 
            new ActionListener () {
                public  void actionPerformed(ActionEvent  ae) {
                    System.out.println("click");
                }
            }
        );
        getContentPane().add(jb);
    }
}

<実行結果>

click buttonを押すと、コンソールにclickと表示されます。
画面右上のXを押すと、プログラムが終了します。



WindowAdapterは抽象クラスです。抽象クラスに対してnewを記述しているように見えますが、
WindowAdapterを継承した無名のクラスをnewしていると考えられます。
このサンプルでは、WindowAdapterクラスを継承し、windowClosingメソッドをオーバーライドしています。
つまり匿名のクラスではextends句を使えませんが、親クラスを継承してクラスを作成する事が可能である事がわかります。
ActionListenerはinterfaceです。interfaceに対してnewを記述しているように見えますが、
匿名クラスはデフォルトでObject classを継承します。
つまり、Objectを継承し、ActionListenerをimplementsした無名のクラスです。
interfaceをimplementsする場合、interfaceの持つ全てのメソッドを実装しなければなりませんが、
ActionListener interfaceが持つメソッドは1つしかありません。



ローカルインナークラスでは、外のクラスからメソッドへの参照が無くなり、ローカル変数が破棄されるても、
ローカルインナークラスのインスタンスが存続する可能性が考えられます。
そのような状態を避けるために、ローカルインナークラスから、ローカル変数を参照する場合、変数に修飾子finalが付いていなければいけません。