こんにちは。まさきです。
今回はJavaで頻繁に使用するpublicやprivateなどの解説をしていきます。
publicなどは意味を理解していないがいつもとりあえず書いている方も多いと思います。
これらは簡単にいうと、publicなどを付けたクラスやメソッドを他のクラスからアクセスを許可するかしないかの指定ができます。
アクセス修飾子とは
アクセス修飾子とは上でも言った通り、他のクラスからアクセスを許可するか/しないかの指定ができます。
アクセス修飾子を一番見るのは以下のmain構文ですね。
public static void main(String[] args){
}
こちらの構文ではpublicが使われていますので、どのクラスからでもアクセスができるように指定されています。
ちなみにこの構文ってとりあえず書いておく暗号ではなくちゃんと意味があるんですよね。知ってました?
他には値が変動しない変数(定数)にはよくprivateを付けた方がよいと言われます。
その理由は定数はそのクラスでしか使用しないため、他のクラスから変に利用されるのを防ぐためです。
このようなアクセスを指定するために利用するのがアクセス修飾子です。
アクセス修飾子の種類と例
アクセス修飾子にはpublicやprivate以外protectedや指定なしも存在します。
わかりずらいですが、指定がされていないのにもちゃんと効果があるのです。
では文章で軽く説明します。
public
クラス、コンストラクタ、変数、メソッドの全てに指定できます。
package packA;
public class Sample { //クラスで指定可能
public Sample{} //コンストラクタで指定可能
public int mum; //変数で指定可能
public void dispSample(){} //メソッドで指定可能
}
publicを指定するとどのクラスからでも利用可能です。
package packB;
import packA;
public class Test {
Sample sample = new Sample(); //アクセス可能
sample.mum = 0; //変数にアクセス可能
sample.dispSample(); //メソッドにアクセス可能
}
4つの中では一番公開範囲が広いです。
protected
コンストラクタ、変数、メソッドに指定できます。クラスには指定できません。
protected class Sample { //クラスで指定可能
protected Sample{} //コンストラクタで指定不可(エラーになる)
protected int mum; //変数で指定可能
protected void dispSample(){} //メソッドで指定可能
}
protectedを指定すると、このクラスを継承したクラスや同一パッケージ内のクラスから利用が可能です。
デフォルトの同一パッケージ内からに加えて、継承したクラスでも利用ができますが、利用することはめったにありません。
デフォルト(指定なし)
クラス、コンストラクタ、変数、メソッドの全てに指定できます。
class Sample { //クラスで指定可能
Sample{} //コンストラクタで指定可能
int mum; //変数で指定可能
void dispSample(){} //メソッドで指定可能
}
同一のパッケージ内のクラスからのみ利用が可能なので、パッケージが違うと利用ができなくなります。
private
コンストラクタ、変数、メソッドに指定できます。クラスには指定できません。
package packA;
private class Sample { //クラスで指定不可(エラーになる)
private Sample{} //コンストラクタで指定不可(エラー)
private int mum; //変数で指定可能
private void dispSample(){} //メソッドで指定可能
}
同一のクラス内からのみアクセス可能なので、他のクラスからは一切アクセスできません。
package packB;
import packA;
public class Test {
Sample sample = new Sample(); //アクセス不可
sample.mum = 0; //変数にアクセス不可
sample.dispSample(); //メソッドにアクセス不可
}
4つの中では一番公開範囲が狭いです。
アクセス修飾子を使い分けるメリット
アクセス修飾子は4つありますが、基本的にpublicとprivateの2つしか使いません。
なぜならprotectedとデフォルトでは同一パッケージ内からのアクセスができるようになりますが、同一のパッケージ内だけ使いたいケースがあまりないからです。
パッケージに分けても結局クラス単位で機能がわかれる場合が多く、クラスから他のクラスに依存したメソッドや変数にアクセスする必要がないです。
なので他クラスからアクセスしていい場合はpublic、他クラスからアクセスさせたくない場合はprivateを指定します。
ではpublicとprivateの使い分けについてです。
publicとprivateを使い分けるメリットはカプセル化にあります。
カプセル化とは、こちらのサイトではこのように説明されています。
カプセル化とは、オブジェクト指向プログラミングにおいて、互いに関連するデータの集合とそれらに対する操作をオブジェクトとして一つの単位にまとめ、外部に対して必要な情報や手続きのみを提供すること。外から直に参照や操作をする必要のない内部の状態や構造は秘匿される。
このようにカプセル化では情報や手続きを外部に提供するのですが、外から参照や操作をされたくないものは秘匿される必要があります。
この「外から参照や操作をされたくない」と言うのを実現するのがprivate修飾子です。
カプセル化のコードの例はこちらです。
public class User{
private int user; //privateで変数は秘匿にする。
public String getUser(){ //メソッドは外部からアクセスできて良い。
return this.user;
}
public String setUser(user){ //メソッドは外部からアクセスできて良い。
this.user = user;
}
}
カプセル化は内部で持つ変数は直接外部から変更できないようにprivateを指定します。
変数を扱うにはゲッターとセッターと呼ばれるメソッドを使います。
ゲッターは変数を取得するメソッド、セッターは変数に値をセットするメソッドです。
こういった仕組みでカプセル化は成り立っています。