Javaのアクセス修飾子の適用範囲をまとめてみました。アクセス修飾子とは、クラス、フィールド、メソッドなどの前に付けるキーワードで他のクラスからのアクセス制限を行います。
クラスやインターフェイスは使われることで役に立つので、基本的に他のクラスに公開されます。クラスやインターフェイスのアクセス修飾子はpublicにするか、指定しないかのどちらかとなります。
Javaのソースファイル(.javaのファイル)にはアクセス修飾子が指定なしのクラスを複数記載することができますが、publicとなるクラスは1つしか記載できません。またpublicとなるクラスがある場合、ファイル名はクラス名と同じにする必要があります。
フィールドやメソッドにもアクセス修飾子があります。フィールドやメソッドに付けられるアクセス修飾子には public、protected、private、指定なしの4つがあります。
クラスのアクセス修飾子とフィールドやメソッドのアクセス修飾子が異なっていた場合にどうなるか?ですが、クラスのアクセス制限のほうが優先されます。
クラスのアクセス修飾子が指定なしだった場合、そのクラスのフィールドやメソッドがpublicであったとしても、異なるパッケージにあるクラスからはそのクラスのフィールドやメソッドにアクセスはできません。
インターフェイスのフィールドやメソッドはすべてpublicとなります。publicを指定しなかったとしてもデフォルトでpublicとみなされます(フィールドやメソッドにpublicをつけてもつけなくても同じということ)。ですのでインターフェイスのフィールドやメソッドのアクセス制限はインターフェイス自体につけられたアクセス修飾子によって決まります。
コンストラクタのアクセス修飾子もフィールドやメソッドと同じく public、protected、private、指定なしの4つとなります。アクセス制限もフィールドやメソッドと同じになります。
コンストラクタがprivateだった場合ですが、他のクラスからインスタンスを生成できなくなります(自分自身でしかインスタンスを生成できない)。privateであるコンストラクタの用途などあるのだろうか?と思うかもしれません。
代表的なクラスでは、Mathクラスのコンストラクタはprivateになっています。Mathクラスはすべてのフィールドとメソッドがstaticで宣言されているのでMathクラスのインスタンスを生成する必要がないのです。
他のクラスからインスタンスを生成されたくないときはコンストラクタをprivateにします。
public class A {
//コンストラクタ
private A() {
;
}
public static void methodX() {
; // 処理を記載
}
}
またGoFのデザインパターンの1つであるSingletonパターンでもprivateなコンストラクタを使っています。Singletonパターンではクラスのインスタンスが1個しか存在しないことを保証します。
Singletonパターンの実装例です。
public class Singleton {
private static Singleton s = new Singleton();
//コンストラクタ
private Singleton() {
;
}
public static Singleton getInstance() {
return s;
}
public void methodX() {
; // 処理を記載
}
}
他のクラスからはgetInstanceメソッドを呼び出して、Singletonクラスのインスタンスを取得します。SingletonクラスのmethodXメソッドのアクセス修飾子はprivate以外にします。
使用例です。
public class MainSample {
public static void main( String[] args ) {
Singleton s = Singleton.getInstance();
s.methodX();
}
}
このようにあえて他のクラスからインスタンスを生成させないために、privateのコンストラクタがあるようです。