クラスの宣言
クラスの宣言、すなわちクラスの定義はファイル名の拡張子がjavaのソースコード内に書くという事は決まっていますが、その書き方にいくつかパターンがあります。例をおって押さえて見ます。
- 一つのソースファイルに一つのクラスを書く
オーソドックスな書き方です。このような簡単なクラスには、Javaのプログラムとして動かせるために、main()というstaticメソッドがあります。
class xxx{ // メンバ以外の要素(コンストラクタなど) // フィールドの宣言 int a; String s; // メソッドの定義 public void hoge(){ ・・・ } }
- 一つのソースファイルに複数のクラスを書く
一つのJavaファイルの中に複数のクラス定義を書く事もできます。普通は中心的なクラスと、その脇役的なクラスが置かれる感じです。
一つのソースファイルの中に複数のクラスを書くときの重要なルールはそれらのクラスの中で「publicなクラスはトップレベルのクラス一つだけ」というルールです。言い換えると一つのソースファイルの中にpublicなクラスが複数あってはいけません。
public class xxx{ // メンバ以外の要素 // フィールドの宣言 int a; String s; // メソッド定義 public void hoge(){ ・・・ } } // xxxクラスの終わり class yyy{ // yyyクラスの内容 }
- クラス定義の中に別のクラスの定義を書く
一つの中心的なクラスと脇役的なクラスは上記のように一つのソースファイルに纏めて書く事ができます。一般的に汎用性がない、または数が少ない場合には、中心的なクラスの内部に書く事もできます。中心クラスの内部に、中心クラス(menber class)と、内部クラス(inner class)として書く事ができるのです。
このような内部クラス・メンバクラスをローカルクラスと呼びます。
このyほうにして、クラスyyyをクラスxxxのメンバにすると、yyyからxxxのフィールドに簡単にアクセスができます。
public class xxx{ // メンバ以外の要素 // フィールドの宣言 int a; String s; // メソッド定義 public void hoge(){ ・・・ } // 内部クラス定義 class yyy{ ・・・ } }
ここで一つ重要なルールがあります。
外側クラスxxxのメソッド内で宣言している変数をそのメソッド内で定義している内部クラスで使うときにはxxxメソッド内とyyyクラスの中で、値の違いがでないようにfinal修飾子が必要となります。ローカル変数の場合はyyyにxxxの変数そのものではなく、コピーが渡されるという仕組みのためです。コピーなのでxxx内で生じた変数がyyyに反映されない事もあるわけなのです。
外側クラスのメソッドないで定義する内部クラスから外側クラスのデータにアクセスする必要があるときは、そのデータを外側クラスのメソッドのローカル変数ではなくクラスのフィールドにせよ。