Javaのアクセス修飾子を完全ガイド!初心者でもわかるpublic、private、protectedの使い方
生徒
「Javaでpublicやprivateって見かけるんですが、これは何ですか?」
先生
「それはアクセス修飾子と呼ばれるもので、クラスやメソッド、変数などのアクセス範囲を制御するためのキーワードです。」
生徒
「アクセス範囲を制御するって、どういうことですか?」
先生
「それでは、public、private、protectedの違いを具体的に見ていきましょう!」
1. アクセス修飾子とは?
Javaのアクセス修飾子は、クラスやメソッド、フィールド(変数)などがどこからアクセスできるかを指定するキーワードです。主に以下の4種類があります。
- public:すべてのクラスからアクセス可能
- protected:同じパッケージ内およびサブクラスからアクセス可能
- (指定なし):同じパッケージ内からのみアクセス可能(デフォルトアクセス)
- private:同じクラス内からのみアクセス可能
これらを適切に使い分けることで、プログラムの安全性や保守性を高めることができます。
2. publicの使い方
publicは、どこからでもアクセスできるようにするための修飾子です。クラスやメソッド、フィールドに付けることで、他のクラスから自由に利用できるようになります。
public class Sample {
public int number = 10;
public void display() {
System.out.println("Number: " + number);
}
}
上記の例では、Sampleクラスのnumberフィールドとdisplayメソッドがpublicとして定義されているため、他のクラスから直接アクセスできます。
3. privateの使い方
privateは、同じクラス内からのみアクセスできるようにする修飾子です。外部からのアクセスを制限し、データの隠蔽(カプセル化)を実現します。
public class Sample {
private int number = 10;
public void display() {
System.out.println("Number: " + number);
}
}
上記の例では、numberフィールドがprivateとして定義されているため、Sampleクラスの外部から直接アクセスすることはできません。
4. protectedの使い方
protectedは、同じパッケージ内およびサブクラスからアクセスできるようにする修飾子です。継承関係にあるクラスでの利用を想定しています。
public class Parent {
protected int number = 10;
}
public class Child extends Parent {
public void display() {
System.out.println("Number: " + number);
}
}
上記の例では、ChildクラスがParentクラスを継承しており、numberフィールドにアクセスしています。protectedとして定義されているため、アクセスが可能です。
5. アクセス修飾子の比較表
各アクセス修飾子のアクセス範囲を表にまとめると、以下のようになります。
| アクセス修飾子 | 同じクラス | 同じパッケージ | サブクラス | 他のパッケージ |
|---|---|---|---|---|
| public | 〇 | 〇 | 〇 | 〇 |
| protected | 〇 | 〇 | 〇 | × |
| (指定なし) | 〇 | 〇 | × | × |
| private | 〇 | × | × | × |
この表を参考に、適切なアクセス修飾子を選択しましょう。
6. アクセス修飾子を使ったサンプルプログラム
以下は、各アクセス修飾子を使ったサンプルプログラムです。
// Main.java
public class Main {
public static void main(String[] args) {
Sample sample = new Sample();
sample.publicMethod();
// sample.privateMethod(); // エラー: privateメソッドにはアクセスできません
// sample.protectedMethod(); // エラー: protectedメソッドにはアクセスできません
}
}
// Sample.java
public class Sample {
public void publicMethod() {
System.out.println("Public method");
}
private void privateMethod() {
System.out.println("Private method");
}
protected void protectedMethod() {
System.out.println("Protected method");
}
}
このプログラムでは、publicMethodはアクセス可能ですが、privateMethodとprotectedMethodはアクセスできません。
7. アクセス修飾子の使い分けのポイント
アクセス修飾子を適切に使い分けることで、プログラムの安全性や保守性を高めることができます。以下のポイントを参考にしましょう。
- public:他のクラスからも利用する必要がある場合に使用
- private:クラス内部でのみ使用し、外部からのアクセスを制限したい場合に使用
- protected:継承関係にあるクラスで利用する場合に使用
- (指定なし):同じパッケージ内でのみ利用する場合に使用
アクセス修飾子を適切に使い分けることで、プログラムの構造を明確にし、バグの発生を防ぐことができます。
8. なぜアクセス修飾子が必要なの?(カプセル化の重要性)
アクセス修飾子を使う最大の理由は、プログラムの「カプセル化」にあります。カプセル化とは、大切なデータや複雑な内部処理を外部から隠し、安全に操作できるようにすることです。
例えば、「銀行口座」のクラスを考えてみましょう。残高(balance)を public にしてしまうと、誰でも勝手に金額を書き換えられてしまいます。しかし、private にして専用の「引き出しメソッド」経由で操作するようにすれば、残高がマイナスにならないかチェックするなどの「ルール」を守らせることができます。
- 誤操作の防止: 外部から直接触らせないことで、データの改ざんや予期せぬバグを防ぎます。
- 内部の変更が楽になる: 外部に公開する部分(public)さえ変えなければ、内部の処理(private)を後から書き換えても他のプログラムに影響を与えません。
「隠せるものはできるだけ隠す(privateにする)」のが、良いプログラムを書くための鉄則です。
9. 実践的なgetterとsetterの活用方法
フィールドを private にして隠した場合、外部からその値を取得したり変更したりするために getter(ゲッター) と setter(セッター) というメソッドを用意するのが一般的です。
実際に、値のチェック機能を備えたサンプルプログラムを見てみましょう。
public class Person {
private int age; // privateで隠す
// 値をセットするメソッド(setter)
public void setAge(int age) {
if (age >= 0) {
this.age = age; // 正しい値のときだけ代入
} else {
System.out.println("エラー:年齢にマイナスは指定できません。");
}
}
// 値を取得するメソッド(getter)
public int getAge() {
return this.age;
}
}
public class Main {
public static void main(String[] args) {
Person p = new Person();
p.setAge(-5); // 不正な値を防ぐ
p.setAge(20); // 正しい値をセット
System.out.println("登録された年齢: " + p.getAge());
}
}
エラー:年齢にマイナスは指定できません。
登録された年齢: 20
このように private と public を組み合わせることで、「データは守りつつ、必要な操作だけを許可する」という柔軟な設計が可能になります。
まとめ
アクセス修飾子を理解することの重要性
ここまで、Javaのアクセス修飾子であるpublic、private、protected、そして指定なしのデフォルトアクセスについて詳しく見てきました。アクセス修飾子は、Javaプログラミングにおいて非常に基本的でありながら、プログラム全体の設計品質や安全性、保守性に大きく影響する重要な要素です。クラス、メソッド、フィールドに対して適切なアクセス範囲を設定することで、意図しない利用や誤った操作を防ぎ、バグの少ない堅牢なコードを書くことができます。
特に初心者のうちは、すべてをpublicにしてしまいがちですが、それではクラスの内部構造が外部に丸見えになり、後から仕様変更が発生した際に修正範囲が広がってしまいます。アクセス修飾子を正しく理解し、必要最小限の公開範囲を意識することが、Javaのオブジェクト指向プログラミングを身につける第一歩と言えるでしょう。
publicとprivateを中心に考える設計
実務や学習の中では、まずpublicとprivateを正しく使い分けられるようになることが大切です。外部から呼び出される必要があるメソッドやクラスのみをpublicにし、それ以外の内部処理やデータはprivateにすることで、クラスの責務が明確になります。これはカプセル化と呼ばれる考え方で、Javaだけでなく多くのプログラミング言語に共通する重要な概念です。
protectedは継承を前提とした設計で活躍しますが、安易に使いすぎるとクラス間の依存関係が複雑になるため、役割を理解した上で使う必要があります。まずはpublicとprivateを軸に設計し、必要に応じてprotectedやデフォルトアクセスを選択する、という順序で考えると理解しやすくなります。
まとめとしてのサンプルプログラム
最後に、これまで学んだアクセス修飾子の考え方を整理するためのシンプルなサンプルプログラムを見てみましょう。クラスの外部から触ってよい部分と、内部で隠しておく部分を意識して設計しています。
public class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void showProfile() {
System.out.println("名前:" + name + " 年齢:" + age);
}
}
この例では、nameとageはprivateにすることで外部から直接変更できないようにしています。その代わり、publicなコンストラクタやメソッドを通して安全に情報を扱えるようにしています。このような設計を意識することで、Javaのクラスはより読みやすく、壊れにくいものになります。
生徒
「アクセス修飾子って、最初はただのルールだと思っていましたが、プログラムの安全性や読みやすさに直結しているんですね。」
先生
「その通りです。特にJavaでは、アクセス修飾子をどう使うかで設計の良し悪しがはっきり分かれます。」
生徒
「これからは、とりあえずpublicにするのではなく、本当に外から使う必要があるかを考えるようにします。」
先生
「それができれば大きな一歩ですね。まずはprivateを基本にして、必要なものだけをpublicにする意識を持ちましょう。」
生徒
「protectedやデフォルトアクセスも、継承やパッケージを意識したときに使えるよう復習してみます。」
先生
「とても良い姿勢です。アクセス修飾子を理解できれば、Javaのクラス設計が一気に楽しくなりますよ。」