アクセス修飾子

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 宣言されていて、インスタンス化されたくないクラスを作るときに特に有効です。



Copyright © 2002 SUGAI, Manabu. All Rights Reserved.