【Java】勝手に変えさせない!「カプセル化」でデータを守る方法
はじめに
みなさんどうも、おげんです。
前回は「コンストラクタ」を使って、オブジェクトが生まれた瞬間にデータをバシッと決める方法を学びました。
「これで完璧なカレーが作れるぞ!」と意気込んでいた私ですが、ある時ふと気づいてしまったんです。
「せっかく作った激辛カレーを、後から誰かに勝手に『甘口』に書き換えられたらどうしよう……」
今の私のコードでは、外(Mainメソッドなど)から誰でも自由に spicy = 1 と書き換えることができてしまいます。
これでは、せっかくのこだわり設定も台無しです。
そこで登場するのが、今回紹介する 「カプセル化」 という考え方です。
これは、大切なデータをカプセルのように包み込んで、外から勝手に触らせないようにするJavaの重要なルール。
実務の世界では、この「カプセル化」をしていないコードは、カギをかけずに外出する家くらい危ないと言われています。
大切なデータをどうやって守るのか、私と一緒に学んでいきましょう!
privateって何のためにつけるの?と思っている人getterとsetterを書くのが面倒だと感じている人- 「プロっぽい」安全なコードの書き方を知りたい人
カプセル化は「ホテルの金庫」
プログラミングで「データを守る」と言われても、最初はピンときませんよね。
私も「別に自分一人で書いてるんだから、勝手に変える人なんていないよ」と思っていました。
でも、イメージしてみてください。
これまでの状態(カギなし)
ホテルの部屋の机の上に、お財布(データ)を出しっぱなしにしている状態です。
これだと、たとえ悪気がなくても、掃除に来たスタッフがうっかり落としてしまったり、誰かが間違えて触ってしまったりするかもしれません。
Javaで言うと、public(公開)な変数に外から誰でもアクセスできる状態です。
カプセル化の状態(金庫を活用)
大切なものは、部屋にある「金庫」の中に入れます。 これがカプセル化です。
- 外からは見えない:金庫を閉めれば、中身(データ)がいくら入っているか外からは分かりません。
- 直接は触れない:金庫を無理やり開けることはできません。
- 「暗証番号」を知っている人だけ:正しい手続きを踏まないと、中身を取り出すことはできません。
なぜ、わざわざ金庫に入れるの?
「使う時にいちいち金庫を開けるのは面倒だな」と感じるかもしれません。
でも、金庫に入れる最大のメリットは「安心感」です。
「誰かに勝手に書き換えられたかも?」「知らないうちに数値が変わってる!」という不安から解放されて、「このデータは安全に守られている」と確信できる。
カプセル化は、プログラムが大きくなればなるほど、私たちを混乱から守ってくれる「心のカギ」になってくれるんです。
private という魔法のカギ
これまで、クラスの中で変数を宣言するときは、特に何も考えずに書いていました。
class Curry {
String name; // これだと「誰でも触れる」状態
int spicy; // これも「誰でも触れる」状態
}ここに、カプセル化の第一歩である private(プライベート) というカギをかけてみます。
カギをかけたコード
class Curry {
private String name; // 自分以外、立ち入り禁止!
private int spicy; // 自分以外、立ち入り禁止!
}たったこれだけです。変数の型の前に private と書き足す。
これだけで、この変数は 「このクラス(Curryクラス)の中からしか触れない」 という特別な存在に変わります。
外から触ろうとするとどうなる?
もし、Mainメソッドなどで勝手に中身をいじろうとすると…
public class Main {
public static void main(String[] args) {
Curry c = new Curry("激辛カレー", 5);
c.spicy = 1; // ❌ ここでエラー!「spicyは見えないよ」とJavaに怒られます
}
}最初にこれを見た時、私は「えっ、エラーになっちゃうなら不便じゃない?」と思いました。 でも、よく考えてみてください。
これは 「勝手に変えようとした侵入者を、Javaがしっかり追い返してくれた」 ということなんです。
「自分の知らないところでデータが変えられるのを、プログラムが未然に防いでくれた」
これこそが private の魔法。
でも、これだけだと「中身を見ることもできない」ので不便ですよね。
そこで必要になるのが、次のステップで学ぶ「専用の窓口」なんです。
窓口を作る「getter」と「setter」
private でカギをかけたままでは、中のデータを見ることもできません。
そこで、「データの確認用」と「データの変更用」に、それぞれ専用の窓口(メソッド)を作ってあげます。
① 中身を教えてもらう「getter」
「今の辛さレベルはいくつ?」と外から聞かれたときに、中身を「コピー」して渡してあげるメソッドです。
// getterの例
public int getSpicy() {
return this.spicy; // 中身をそっと教えてあげる
}② 中身を安全に変える「setter」
「辛さを変えて!」と頼まれたときに、中身を書き換えるメソッドです。
// setterの例
public void setSpicy(int spicy) {
// ここでチェックができる!
if (spicy < 0) {
System.out.println("辛さにマイナスは設定できません!");
} else {
this.spicy = spicy; // 安全なら書き換える
}
}私が「setterって便利!」と一番感動したのは、変なデータが入ってくるのを防げる点です。
もし private にせず、外から直接書き換えられたら、誰かがうっかり spicy = -100; なんてあり得ない数字を入れてしまうかもしれません。
でも、setter という窓口を通すルールにすれば、「もしマイナスの数字が来たら無視する」 というガードを張ることができます。
直接触らせないのは、意地悪をしているわけではなく、「正しく安全にアプリを動かすため」 の優しさなんですね。
なぜそんな面倒なことをするの?
「変数を private にして、わざわざ getter と setter を作るなんて、二度手間じゃない?」
正直に言います。私も最初はそう思っていました。
自分で自分のコードを縛っているような、変な感覚だったんです。
でも、ある時気づいたんです。これは「未来の自分やチームへの、最高の優しさ」なんだと。
理由①:犯人探しをしなくて済む
もし、アプリが動いている途中で「なぜかカレーの辛さが -100 になっている」というバグが見つかったとします。
- カプセル化していない場合:誰が、どこのコードで勝手に書き換えたのか、全部のファイルを調べないとわかりません。
- カプセル化している場合:
setSpicyメソッドの中だけを調べればいいんです。窓口は一つしかないから、犯人(バグの原因)を特定するのがめちゃくちゃ早いんです。
理由②:あとからの変更が「無音」で終わる
例えば、後になって「辛さの単位を『レベル』から『スコヴィル値』に変えたい」と思ったとします。
もし外から直接変数を触っていたら、その変数を使っている何十箇所ものコードをすべて書き換える大工事になります。
でも、カプセル化していれば、「設計図の中(getter/setter)」を少し直すだけで、外のコードはそのままでOKなんです。
まとめ:カプセル化は「守りの要」
今回は、大切なデータを安全に扱うための「カプセル化」について学びました。
- カプセル化とは、データにカギをかけて、外から直接触らせないようにすること。
privateを使うことで、そのクラスの「プライバシー」を守り、勝手な書き換えを防ぐ。getterは中身を安全に「見る」ための窓口。setterは中身を安全に「変える」ための窓口。ここで変なデータが入らないようチェック(ガード)できる。
「わざわざ窓口を作るなんて面倒…」と思っていた私も、今では「カギがかかっていないと怖くてコードが書けない!」と思うようになりました(笑)。
プログラミングは、自由奔放に書くよりも、あえて「ルール(制約)」を作ることで、結果的にミスが減り、開発がスムーズになります。
現場に入ると、このカプセル化は「呼吸をするように当たり前」に使われます。
今のうちにこの感覚を掴んでおけば、実務のコードを読んだときも「お、しっかりカギがかかってるな!」と冷静に向き合えるはずです。
今回も最後まで読んでいただき、ありがとうございました!
また次の一歩を、着実に進めていきましょう。
