Revised: Sep./09th/2002; Mar./27th/2002
修飾子の節で説明したとおり、クラス、メンバ変数(フィールド)、メソッド、コンストラクタには修飾子を指定できます。それぞれに指定できる修飾子は異なり、言語仕様として定義されています。この中で、アクセスの制限を指定する修飾子は共通です。
次の表はアクセス制限修飾子のリストであり、下に行くほど制限が弱まっています。
private |
同じクラス内からしか呼び出せないが、同じクラスから作られたオブジェクト同士であれば、相互の private メンバーにアクセスできる。 |
---|---|
省略 | 同じパッケージ内からしか呼び出せない。 |
protected |
同じパッケージか、そのサブクラスからしか呼び出せない。 |
public |
どこからでも呼び出せる。 |
「省略」と言うのは、ここで挙げた三つのアクセス修飾子を指定しないことを意味しています。通常は、アクセス制限とは関係のないほかの修飾子が指定されていることが多いでしょう。
簡単なアクセス制限ですがとても強力で効果的なアクセス制限を提供できます。
オブジェクト指向のコーディングは部品の組み合わせです。別個に作った部品同士がメッセージを送りあって全体の処理を進めていきます。
このとき、部品を private
修飾しておけば、当該クラス内からのアクセスしか存在せずに、他のクラスから利用されることが無いので、次のようなメリットが期待できます:
private
修飾しておけば、部品の独立性が高まり、部品内部での変更が外部に影響を与えることが無く、予め想定していた以外の不正な利用を防ぐことが出来ます。これをカプセル化と呼びます。
原則として、全てのメンバー変数(フィールド)は private 修飾して、public なメソッドを通してアクセスされるようにしておきます。public なメソッドは、他のオブジェクトと会話するインタフェースとなるので、インタフェース・メソッドと呼ぶことができます。メソッドも、全て private にしておき、必要最小限のメソッドだけを public 修飾すると良いでしょう。
フィールドとは、クラスのメンバーである変数のことです。ローカル変数とは異なり、オブジェクトが持続する限り持続し続ける変数です。
次のサンプルはフィールド修飾子の例です。アクセス制限の修飾子のなかの private
が指定されていますから、この変数には当該クラス内からしか参照できません。
private String name;
メソッドとは、クラスのメンバーであり、このクラスから作られるオブジェクトが持つ機能(実行できる制御)を記述した部分のことです。
次のサンプルはメソッドの例です。アクセス制限修飾子が protected
に指定されていますから、このクラスが属しているパッケージに属する他のクラスか、このクラスを継承しているサブクラスから呼ぶことができます。
protected String getName() {
return name;
}
クラスにもここで挙げた全ての修飾子を指定することが出来ます。但し、修飾子ごとに指定できるクラスの形式が異なっているので少々複雑です。
クラスは内部に別のクラスを定義することも可能です。クラスの内部に宣言したクラスを内部クラスと呼び、一番外側のクラスとは異なった扱いを受けます。
一番外側のクラスには public
だけが指定可能です。但し、ソースファイル (*.java
) の中で public
クラスは一つでなければならず、クラス名とソースファイル名を一致させる必要があります。
アクセス修飾子を指定しないクラスは、同じパッケージ内のクラスからしか参照できませんが、 public
クラスはあらゆるクラスから参照できます。ですから、アクセスを制限したいクラスに対して他のクラスからの参照を仲介する為の出入り口として public
クラスを定義することができます。
次のサンプルでは、アクセス修飾を指定していないクラス Test
を、他のパッケージから利用するために、public
修飾子を指定したクラス ACTest
を作成しました。ソースファイル名は ACTest.java
であることが必要です。
ACTest.java
:
// 一番外側のクラス
class Test {
String name;
}
// 一番外側のクラス
public class ACTest extends Test {
// Test クラス型変数をメンバーとして定義
private Test obj;
// obj にインスタンスをセットするメソッド
public void setName(String str) {
// Test クラスをインスタンス化し、
// Test クラス型変数 obj に Test クラス型オブジェクトの参照をセット
obj = new Test();
// Test クラス型オブジェクトの変数 name にメソッド引数 str をセット
obj.name = str;
}
// obj オブジェクトの name 変数を返すメソッド
public String getName(){
// Test クラス型オブジェクトの name 変数を返す
return obj.name;
}
}
このソースコードを格納した *.java
ファイルの名前は、 ACTest.java
であることが必要です。
C:\Java>javac ACTest.java C:\Java>
クラスに属し、クラス/オブジェクトと共に持続し続ける要素を、クラスのメンバーと呼びます。メンバーはサブクラスに継承されえる要素です。 Java 言語仕様でクラスのメンバーとして許される要素は、クラス、インタフェース、フィールド及びメソッドが定義されています。
protected
, private
はその定義上、クラスには指定できなそうな感じですが、クラスのメンバー としてあらわれるクラス (member class) に対しては指定可能です。
メンバークラスに関しては後で詳しく説明しますが、他のクラス内部に宣言されたクラスのことです。但し、クラスのメソッド内部に書かれた内部クラスはメンバークラスではありません。
次のサンプルは、本節までではまだ扱っていない知識を使っています。
// 一番外側のクラス class EnclosingClass { // EnclosingClass のメンバークラス private class MemberClass { // MemberClass のメンバークラス private class InnerClass { private String name; public void setName(String str) { name = str; } } // MemberClass のメソッド public void setName(String str) { InnerClass obj = new InnerClass(); obj.setName(str); } } // EnclosingClass のメソッド public void setName(String str) { MemberClass obj = new MemberClass(); obj.setName("Tochihara"); } }
C:\Java>javac EnclosingClass.java C:\Java>
コンストラクタとは、クラスからオブジェクトを作るときに、クラスで実装された定義を初期化する部分です。書式としてはメソッドに似ており、特殊なメソッドだと考えて良いことが殆どです。オブジェクトを作成することを、クラスのインスタンス化と呼びますが、このときコストラクタが必ず呼ばれています。
コンストラクタに定義されている修飾子は、ここで紹介するアクセス修飾子の三つだけです。
特に問題になるのは private
修飾子です。この修飾子は、当該クラス内部からのアクセス以外は拒否します。したがって、コンストラクタがこの修飾子を指定されていれば、当該クラスの内部から自分自身をインスタンス化することしか出来ないということになります。変数やメソッドなどのメンバーが static
宣言されていて、インスタンス化されたくないクラスを作るときに特に有効です。