【Java】クラスは「設計図」、オブジェクトは「実体」?身近な例で攻略しよう
はじめに
みなさんどうも、おげんです。
Javaの勉強を進めていると、必ず耳にする「オブジェクト指向」という言葉。
参考書を開けば「クラス」や「インスタンス」といった難しい漢字やカタカナが並び、「うっ、難しそう……」と本を閉じたくなる人も多いはず。
実は、私もその一人でした(笑)。
でも、安心してください。
「オブジェクト指向」というのは、決して魔法でも何でもありません。
簡単に言うと、「バラバラだったデータや処理を、現実世界と同じように『モノ(オブジェクト)』として扱おう!」という、とても合理的な考え方のことなんです。
これまでは「計算のやり方」を書いてきましたが、これからは「便利な道具(モノ)」を作り、それを組み合わせてアプリを動かしていく、一段上のステップへと進みます。
Javaの本当の面白さは、ここから始まると言っても過言ではありません。
私と一緒に、その扉を叩いてみましょう!
- 「クラス」と「インスタンス」の違いがイマイチわからない人
- 参考書の難しい説明で挫折しかけている人
- Javaらしい、効率的なプログラムの書き方を知りたい人
クラスは「たい焼きの型」
「クラス」と「オブジェクト」の違いを説明するとき、よく使われるのが 「たい焼きの型」と「実際のたい焼き」 の関係です。
クラス = 「たい焼きの型(設計図)」
クラスは、あくまで「形」を決めるだけのものです。
「どんな形にするか」「どれくらいの大きさにするか」というルールは持っていますが、型そのものを食べることはできませんよね。
Javaの世界でも同じです。
クラスを作っただけでは、まだプログラムの中で動かすことはできません。
オブジェクト = 「焼き上がったたい焼き(実体)」
型に生地を流し込んで、実際に焼き上がったものが「オブジェクト(インスタンス)」です。
これなら、私たちは手に取って食べることができます。
ここで注目してほしいのが、「型(クラス)は1つあれば、たい焼き(オブジェクト)は何個でも量産できる」 という点です。
さらに、焼くときに中身を変えることだってできます。
- 1つ目のたい焼きには「あんこ」を入れる
- 2つ目のたい焼きには「カスタード」を入れる
- 3つ目のたい焼きには「チョコ」を入れる
これらはすべて同じ「たい焼きの型」から生まれていますが、それぞれ「中身(データ)」が違う、別々のたい焼きです。
Javaもこれと全く同じで、「設計図(クラス)」を1枚書いておけば、中身のデータが少しずつ違う「実体(オブジェクト)」をいくらでも自由に生み出すことができるんです。
ゲームのキャラクターで例える「クラス」と「実体」
多くの人が一度は遊んだことがある「RPG(ロールプレイングゲーム)」の世界を思い浮かべてみてください。
クラス = 「ジョブの定義(設計図)」
ゲームのシステムの中には、「戦士」や「魔法使い」といったジョブの定義があります。
- 戦士なら: HPが高く、剣で攻撃するスキルを持っている。
- 魔法使いなら: HPは低いけれど、強力な魔法を使える。
これはあくまで「戦士とはこういうものだ」というルール(クラス)です。
このルールそのものがモンスターと戦ってくれるわけではありませんよね。
オブジェクト = 「実際に操作するキャラクター」
その「戦士」という設計図をもとに、私が作成して画面の中で動かしているキャラクターがオブジェクト(実体)です。
- 私の戦士: 名前は「げん」、レベルは10。
- 村人Aの戦士: 名前は「タロウ」、レベルは3。
二人とも「戦士」という同じ設計図(クラス)から生まれていますが、名前もレベルも、今持っているHPの残りも違います。
設計図は同じでも、個別のデータを持っている実体は別物、というのがオブジェクト指向の面白いところです。
メソッドは「コマンド」
さらに、この設計図には「特技(コマンド)」も定義されています。
「斬りつける」という特技は戦士なら誰でも持っていますが、それを実行するのは個別のキャラクターです。
私が「斬れ!」と命令(メソッドを呼び出し)すると、私の操作するキャラクターというオブジェクトがそのアクションを実行してくれる。
これが、Javaで「オブジェクトを作って、メソッドを動かす」という流れの正体なんです。
なぜ「設計図(クラス)」が必要なの?
「わざわざ設計図なんて作らなくても、その都度データを書けばいいんじゃない?」
私も最初はそう思っていました。
でも、同じようなモノをいくつも扱うようになると、設計図がない世界はとても不便だと気づいたんです。
「料理のレシピ」で考えてみる
例えば、私が「カレー」を作るとします。
- クラス = カレーのレシピ(設計図) 「具材を入れる」「煮込む」「ルーを溶かす」という手順や、必要な材料が書かれています。
- オブジェクト = 実際に出来上がったカレー(実体) レシピをもとに、私がキッチンで作った「今日の晩ごはん」です。
もしレシピ(設計図)がなかったらどうなるでしょうか?
毎回「えーっと、次は何をするんだっけ?」といちから考え直さなければなりませんし、味もバラバラになってしまいますよね。
設計図があることの3つのメリット
プログラミングでクラスを作るのも、これと同じ理由です。
- 同じものを何度でも作れる: 一度レシピ(クラス)を書いておけば、いつでも同じ品質の「カレー(オブジェクト)」を量産できます。
- 中身を少しだけ変えられる: 基本のレシピは同じでも、ある時は「甘口」、ある時は「激辛」といったように、中身のデータ(辛さ)だけを変えた別々のカレーを簡単に作れます。
- まとめて修正できる: 「隠し味にソースを入れる」とレシピを書き換えれば、次から作るすべてのカレーが美味しくなります。
クラスを使う一番の理由は、「複雑なものを、整理して、効率よく扱うため」 です。
大規模なアプリになればなるほど、この「共通のルール(設計図)」があることで、迷わずに開発を進めることができるようになるんです。
クラスを作って動かしてみる(コード例)
では、実際に「カレーのレシピ(クラス)」を書いて、そこから「甘口カレー」と「激辛カレー」という2つの「実体(オブジェクト)」を作ってみます。
まずは設計図である Curryクラス です。
// これが設計図(クラス)です
class Curry {
String name; // カレーの名前
int spicy; // 辛さレベル
// 「食べる」という振る舞い(メソッド)
void eat() {
System.out.println(name + "(辛さ:" + spicy + ")をいただきます!");
}
}次に、この設計図を使って、実際にカレーを「召喚」して動かすコードです。
public class Main {
public static void main(String[] args) {
// 1. 甘口カレーを召喚!(newを使って実体を作る)
Curry mildCurry = new Curry();
mildCurry.name = "おこさまカレー";
mildCurry.spicy = 1;
// 2. 激辛カレーを召喚!
Curry spicyCurry = new Curry();
spicyCurry.name = "激辛レッドカレー";
spicyCurry.spicy = 5;
// それぞれに「食べて」と命令する
mildCurry.eat(); // 「おこさまカレー(辛さ:1)をいただきます!」
spicyCurry.eat(); // 「激辛レッドカレー(辛さ:5)をいただきます!」
}
}コードの中に出てくる new という言葉。
これが、設計図から実体を作り出すための「召喚の呪文」です。
new Curry() と書くたびに、メモリの中に新しいカレーが一つずつ出来上がります。
mildCurry と spicyCurry は、同じ設計図から生まれましたが、中身のデータ(名前や辛さ)はそれぞれ独立して持っている、全く別の「モノ」なんです。
まとめ:Javaの世界は「モノ」でできている
今回は、Java学習最大の壁とも言われる「クラスとオブジェクト」について解説しました。
- クラスは「設計図」や「レシピ」。ルールを決めるもの。
- オブジェクトは、設計図から生まれた「実体」。実際に動くもの。
newという呪文を使うことで、設計図からいくらでも実体を量産できる。- 同じ設計図から生まれても、中身のデータ(変数)はそれぞれが独立して持っている。
最初は「わざわざ設計図を作るなんて面倒だな」と感じるかもしれません。
でも、これからプログラムが大きくなっていくにつれて、この「役割ごとに設計図を分ける」という考え方が、コードをスッキリと保つための最強の味方になってくれます。
これからは、コードを書くときに「これはどんなモノ(オブジェクト)だろう?」「どんな設計図が必要かな?」と少しだけ意識してみてください。
それだけで、あなたの書くコードはぐっと「Javaらしく」進化していくはずです。
私と一緒に、この広大なオブジェクト指向の世界を楽しんでいきましょう!
今回も最後まで読んでいただき、ありがとうございました。
また次の一歩を、共に進めていきましょう。
