
Java入門|メソッドを公開して安全に操作するしくみ
中身は守り、使い方は開く。public メソッドがあると、クラスは安全で使いやすい部品になる
private を学ぶと、「大事なフィールドは外から直接触れないように隠せばよい」という感覚が見えてきます。これはとても大切な第一歩です。ですが、フィールドを隠しただけでは、今度はクラスの外から必要な設定すらできなくなってしまいます。戦士の情報を守りたいのに、名前も戦闘力も気の量もまったく設定できないのでは、クラスを実際のプログラムで使うことが難しくなってしまいます。
そこで登場するのが、public メンバです。ドラゴンボールで考えるなら、戦士の内部状態そのものは勝手に触らせないようにしながら、「正しい手順で状態を変えるための技」だけは外に公開しておくイメージです。たとえば気の量を設定するときも、外からいきなり energy に値を入れさせるのではなく、専用のメソッドを通して、正しい値かどうかを確認してから反映するようにできます。ここでは、private と public をどう使い分けるのか、そしてその考え方がどうカプセル化につながるのかを、ドラゴンボールのたとえでやさしく整理していきます。
private だけでは、安全でも使いにくい
前回学んだように、フィールドを private にすると、クラスの外から直接アクセスできなくなります。
たとえば Saiyan クラスのフィールドを次のようにしたとします。
class Saiyan
{
private String name;
private int power;
private double energy;
}このようにしておけば、main メソッドのようなクラスの外側からは、
goku.name = "悟空";
goku.power = 9000;
goku.energy = -10.0;のような直接代入はできなくなります。
これはとても安全です。
でもその一方で、
- 正しい名前を設定したい
- 正しい戦闘力を設定したい
- 正しい気の量を設定したい
という普通の操作までできなくなってしまいます。
つまり private は、中身を守る力は強いけれど、それだけでは「安全に使う方法」がまだ足りない状態なのです。
そこで必要になるのが public メソッド
この問題を解決するために使うのが public メソッドです。
public をつけたメンバは、クラスの外から利用できます。
つまり、フィールドは private で守りつつ、必要な操作だけを public メソッドとして公開すればよいわけです。
ドラゴンボールで言えば、
- 戦士の内部データそのものは非公開
- でも正式な手順で気を整える技や、状態を表示する技は公開
という設計です。
この考え方を使うと、外からは「決められた安全な入口」だけを通して操作できるようになります。
これが、クラスを安全で使いやすい部品にしていく基本の発想です。
直接代入ではなく、専用メソッドを通して設定する
では、実際にどう書くのかを見てみましょう。
今回の考え方をドラゴンボールの世界に置きかえて、プログラムを整理すると次のようになります。
ファイル名:Sample2.java
class Saiyan
{
private String name;
private int power;
private double energy;
public void setStatus(String n, int p, double e)
{
if (e > 0 && e < 1000) {
name = n;
power = p;
energy = e;
System.out.println("戦士の名前を" + name + "に戦闘力を" + power + "に気の量を" + energy + "にしました。");
}
else {
System.out.println(e + "は正しい気の量ではありません。");
System.out.println("気の量を変更できませんでした。");
}
}
public void show()
{
System.out.println("戦士の名前は" + name + "です。");
System.out.println("戦闘力は" + power + "です。");
System.out.println("気の量は" + energy + "です。");
}
}
class Sample2
{
public static void main(String[] args)
{
Saiyan goku = new Saiyan();
// goku.name = "悟空";
// goku.power = 9000;
// goku.energy = -10.0;
goku.setStatus("悟空", 9000, 20.5);
goku.show();
System.out.println("正しくない気の量(-10.0)を指定してみます・・・");
goku.setStatus("悟空", 9000, -10.0);
goku.show();
}
}このコードでは、name、power、energy は private なので、外から直接触れません。
その代わりに、setStatus() と show() が public になっています。
つまり、クラスの外からは
- setStatus() で状態を設定する
- show() で状態を表示する
という安全な使い方だけができるようになっています。
public メソッドの中で値をチェックできる
このサンプルのいちばん大事な点は、setStatus() の中で、値が正しいかどうかをチェックしているところです。
if (e > 0 && e < 1000) {
name = n;
power = p;
energy = e;
...
}
else {
...
}ここでは、気の量 e が 0 より大きく、1000 より小さいときだけ、energy に代入しています。
つまり、正しい範囲の値だけを受け入れるようにしているわけです。
もし不正な値が渡されたら、energy は変更しません。
これがとても大切です。
以前のように外から直接
goku.energy = -10.0;と書けてしまうなら、防ぎようがありませんでした。
でも今は必ず setStatus() を通るので、その中でチェックできます。
ドラゴンボールで言えば、戦士の気を調整するときに、必ず「この値は自然な範囲か」を確認してから反映しているようなものです。
誤った値を防げるので、安全性が上がる
この設計のよいところは、外からどんな値が渡されても、クラス自身が最終チェックをできるところです。
たとえば、
goku.setStatus("悟空", 9000, 20.5);なら、20.5 は正しい値なので設定されます。
でも、
goku.setStatus("悟空", 9000, -10.0);なら、-10.0 は不正な値なので設定されません。
実行結果のイメージはこうなります。
戦士の名前を悟空に戦闘力を9000に気の量を20.5にしました。
戦士の名前は悟空です。
戦闘力は9000です。
気の量は20.5です。
正しくない気の量(-10.0)を指定してみます・・・
-10.0は正しい気の量ではありません。
気の量を変更できませんでした。
戦士の名前は悟空です。
戦闘力は9000です。
気の量は20.5です。最後の show() を見ると、気の量は 20.5 のままです。
つまり、不正な値はクラスの中に入らなかったわけです。
このように、public メソッドを入口にして、そこで値を確認することで、クラスの安全性はかなり高まります。
private と public を使い分けるのが大切
ここで大事なのは、private と public は対立するものではなく、役割分担して一緒に使うものだということです。
表で整理するとこうなります。
| 修飾子 | 役割 |
|---|---|
| private | クラスの外から直接触らせない |
| public | クラスの外から使えるように公開する |
そして、よくある基本形は次のようになります。
| メンバの種類 | よくある設計 |
|---|---|
| フィールド | private |
| メソッド | public |
つまり、
- データそのものは守る
- 操作方法だけを公開する
という形です。
ドラゴンボールで言えば、
- 戦士の内部状態は守る
- 状態を変える正式な技だけ外に見せる
という考え方です。
この使い分けが、クラス設計のとても重要な基本になります。
カプセル化とは何か
ここで出てくる大切なキーワードが、カプセル化です。
カプセル化とは、
データと機能をひとまとめにし、必要に応じてメンバを保護すること
です。
今回の Saiyan クラスで考えると、
- name、power、energy というデータがある
- setStatus()、show() という機能がある
- データは private で守っている
- 機能は public で公開している
という構造になっています。
これがまさにカプセル化の考え方です。
ドラゴンボールでたとえるなら、戦士の大事な中身をカプセルの中に入れて守り、外からは決められた操作口だけを使わせるイメージです。
だから「カプセル化」という言葉は、とても感覚に合っています。
カプセル化のよいところ
カプセル化のよいところは、クラスを使う人が、危ない使い方をしにくくなることです。
たとえば、Saiyan クラスを設計する人と、それを使って別のプログラムを書く人が別々だったとします。
そのとき、フィールドが全部丸見えで自由に触れる設計だと、使う人はうっかり不自然な値を入れてしまうかもしれません。
でも、
- フィールドは private
- 安全な操作メソッドだけ public
という設計にしておけば、使う人はその公開された使い方に従うだけで、自然な範囲の操作をしやすくなります。
つまりカプセル化は、
クラスを作る人にも、クラスを使う人にもやさしい設計
だと言えます。
クラスの仕様部分と利用部分を分けて考えやすくなる
これまで学んできたように、クラスを宣言する部分と、そのクラスを使う部分は分けて考えられます。
- クラス宣言側
→ 戦士の仕様を作る側 - main メソッド側
→ その仕様を使ってプログラムを書く側
カプセル化ができていると、仕様を作る側が安全な使い方をあらかじめ用意しておけます。
すると、利用する側は、その使い方に沿ってプログラムを書くだけで、不具合の起きにくいコードを書きやすくなります。
これは実際の開発でもとても重要です。
クラスは、自分だけが使うとは限りません。あとから別の人が使うこともあります。
だからこそ、最初から安全に使える形で公開しておくことが大事なのです。
修飾子を省略するとどうなるのか
ここで少しだけ触れておきたいのが、private や public を省略した場合です。
これらは修飾子と呼ばれます。
何も書かない場合、そのメンバは「同じパッケージの中からアクセスできる」扱いになります。
今の段階では、同じファイルに書かれたクラス同士でアクセスできていたのは、このしくみが関係しています。
ただし、ここではまず
- private は外から直接アクセスできない
- public は外から利用できる
という対比をしっかり押さえておけば十分です。
パッケージの詳しい話は、あとで学ぶ内容として置いておいて大丈夫です。

この図では、中央の Saiyan クラスの中が上下に分かれています。
上側には private フィールドがあり、鍵アイコンで守られていることが表されています。これは、内部データを外から直接触れないようにしている状態です。
下側には public メソッドがあり、こちらは開いた扉のアイコンで表されています。
つまり、外から利用してよい入口はここだ、ということです。
左側の Sample2 クラスからは、setStatus(...) や show() へは矢印が通っています。
これは public メソッドなので外から使えることを示しています。
一方、goku.energy = -10.0 は途中で遮られていて、private フィールドへ直接入れないことがわかります。
この図を見ると、「全部を閉じる」のではなく、「危険な直通ルートを閉じて、安全な入口だけを開く」のがカプセル化だと理解しやすくなります。
いちばん大事な感覚
「メソッドを公開して安全に操作するしくみ」で大切なのは、次の感覚です。
- private でフィールドを守るだけでは、外から必要な設定もできなくなる
- そこで public メソッドを公開して、安全な操作口を用意する
- public メソッドの中で値をチェックすれば、不自然な値を防げる
- private と public を使い分けることで、クラスは安全で使いやすい部品になる
- データと機能をまとめ、必要なメンバを保護する考え方がカプセル化
ドラゴンボールで言いかえるなら、
- 戦士の内部状態は勝手にいじらせない
- でも正式な技や操作手順は公開しておく
- その技の中で正しい値かを確認してから状態を変える
- だから、戦士として不自然な状態が生まれにくくなる
ということです。
この感覚がつかめると、クラスはただの設計図ではなく、自分の中身を守りながら、外には安全な使い方だけを見せる部品として見えてきます。ここから先のオブジェクト指向の理解も、ぐっと深まっていきます。
