Java入門|クラスから実体を作る仕組み

設計図だけでは戦えない。クラスから実体を生み出して、はじめてプログラムは動き出す

クラスの基本を学ぶと、Javaでは情報や機能をひとまとめにして整理できることが見えてきます。けれども、クラスを宣言しただけでは、まだ実際に動く登場人物は生まれていません。あくまで「こういう戦士を作れますよ」という設計図が用意された段階です。

ドラゴンボールでたとえるなら、サイヤ人という設計図を用意しただけでは、まだ悟空もベジータも悟飯もその場に現れていない状態です。名前も決まっていなければ、戦闘力も決まっていません。実際に戦わせたり、状態を表示したりするためには、その設計図をもとにして、実体をひとつずつ作る必要があります。

この「設計図から実際の存在を作る」考え方が、オブジェクトの作成です。ここでは、クラスとオブジェクトの関係をドラゴンボールの世界でイメージしながら、クラスから実体を作るしくみをやさしく整理していきます。

クラスを作っただけでは、まだ実体はない

クラスは、情報と機能をまとめた設計図です。
たとえば、サイヤ人クラスを考えると、次のような情報や機能を持たせることができます。

分類内容
情報名前、戦闘力、技、変身状態
機能攻撃する、変身する、状態を表示する

イメージとしては、こんな形です。

class サイヤ人
{
    名前;
    戦闘力;
    技;
    変身状態;

    攻撃する()
    {
        技で攻撃する;
    }

    状態を表示する()
    {
        名前を表示する;
        戦闘力を表示する;
    }
}

この段階では、サイヤ人という種類の戦士に共通するルールは用意できています。
でも、まだここには悟空もベジータも出てきていません。

たとえば、

  • 名前が悟空なのか
  • 戦闘力がいくつなのか
  • 技がかめはめ波なのか
  • 今の変身状態が何なのか

といった具体的な内容は、まだ何も決まっていません。

つまりクラスだけでは、共通の型はあるけれど、具体的な1人はまだ存在していないのです。

オブジェクトとは、設計図から作られた実体

ここで登場するのがオブジェクトです。

オブジェクトは、クラスという設計図をもとにして作られた実際の存在です。
ドラゴンボールで考えるなら、サイヤ人クラスという設計図から、

  • 悟空
  • ベジータ
  • 悟飯

のような具体的な戦士を作ることが、オブジェクトの作成です。

表で整理すると、こうなります。

用語ドラゴンボールでのイメージ
クラス戦士の設計図
オブジェクト実際に存在する悟空やベジータ
オブジェクトの作成設計図から1人の戦士を生み出すこと

ここで大事なのは、クラスは1つでも、そこから作られるオブジェクトは1つとは限らないことです。
同じサイヤ人クラスからでも、悟空のオブジェクト、ベジータのオブジェクト、悟飯のオブジェクトというように、複数の実体を作ることができます。

クラスを利用するということは、オブジェクトを作ること

クラスを宣言しただけでは、まだ設計図があるだけです。
実際にそのクラスを使いたいなら、オブジェクトを作らなければいけません。

この感覚はとても大切です。
なぜなら、プログラムの中で実際に情報を持たせたり、動かしたりする相手は、クラスそのものではなく、クラスから作られたオブジェクトだからです。

ドラゴンボールでいえば、

  • サイヤ人という設計図がある
  • その設計図から悟空という実体を作る
  • 悟空に名前や戦闘力を持たせる
  • 悟空に攻撃させる

という流れになります。

つまり、
クラスは土台、オブジェクトは実際に動く存在
という関係です。

オブジェクトを作る前に、まず変数を用意する

Javaでは、オブジェクトを使うときに、いきなり何もないところから扱うのではなく、まずそのオブジェクトを扱うための変数を用意します。

これは、サイヤ人クラスのオブジェクトを入れて扱うための箱を準備するイメージです。

たとえば、悟空を入れるための変数を用意したいとします。
そのときは、クラス名を型として使って変数を宣言します。

サイヤ人 悟空;

この1行は、
サイヤ人型の変数 悟空 を宣言した
という意味になります。

ここでのポイントは、まだこの時点では悟空という実体が作られていないことです。
あくまで「サイヤ人を入れられる変数を用意した」だけです。

イメージでいうと、まだ空の状態です。

段階状態
サイヤ人 悟空;サイヤ人を入れられる箱を用意しただけ
まだ実体はない悟空そのものはまだ生まれていない

この最初の一歩を理解しておくと、あとでオブジェクト作成の流れがかなり見えやすくなります。

new を使って実体を作る

次に必要なのが、実際にオブジェクトを作る作業です。
ここで使うのが new です。

new は、設計図から新しい実体を作るための書き方です。

ドラゴンボールでいえば、サイヤ人クラスという設計図から、新しい戦士を1人出現させるイメージです。

悟空 = new サイヤ人();

この1行では、サイヤ人クラスから新しいオブジェクトを作り、それを変数 悟空 に代入しています。

ここでようやく、変数 悟空 を通して、そのオブジェクトを扱えるようになります。

流れを順番に見るとこうです。

① 変数を宣言する

サイヤ人 悟空;

➁ new でオブジェクトを作って代入する

悟空 = new サイヤ人();

この2段階によって、サイヤ人クラスのオブジェクトを使う準備が整います。

2つの手順をドラゴンボールでイメージする

この流れは、ドラゴンボールでたとえるととてもわかりやすいです。

最初の段階

サイヤ人 悟空;

これは、
「悟空という名前で、サイヤ人を扱うための枠を用意した」
という状態です。

まだこの段階では、悟空は実際には現れていません。
名前を書いた名札だけ置いてあるような感覚です。

次の段階

悟空 = new サイヤ人();

ここで初めて、サイヤ人の設計図から新しい実体が作られ、その実体が悟空という変数で扱えるようになります。

この2つをまとめると、

  • 先に扱うための変数を作る
  • 次に new で実体を作る
  • その実体を変数に入れる

という順番になります。

宣言と作成は1行にまとめることもできる

Javaでは、この2つの手順を別々に書くこともできますし、1行にまとめることもできます。

別々に書く場合はこうです。

サイヤ人 悟空;
悟空 = new サイヤ人();

1行にまとめる場合はこうです。

サイヤ人 悟空 = new サイヤ人();

意味は同じです。
どちらも、サイヤ人型の変数 悟空 を用意して、そこに新しいサイヤ人オブジェクトを入れています。

表にすると違いが見やすいです。

書き方意味
サイヤ人 悟空;
悟空 = new サイヤ人();
宣言と作成を分けて書く
サイヤ人 悟空 = new サイヤ人();宣言と作成を1行で書く

入門段階では、最初は2行で考えたほうが流れを理解しやすいです。
慣れてきたら1行で書く形も自然に読めるようになります。

同じクラスから複数の実体を作れる

クラスの便利さがはっきり見えてくるのは、同じ設計図から複数の実体を作れるところです。

たとえばサイヤ人クラスから、悟空とベジータをそれぞれ作ることができます。

サイヤ人 悟空 = new サイヤ人();
サイヤ人 ベジータ = new サイヤ人();

この2行で作られたのは、どちらもサイヤ人クラスのオブジェクトです。
でも、それぞれ別の実体です。

このあとで、それぞれに違う情報を持たせれば、

  • 悟空は名前が悟空、技がかめはめ波
  • ベジータは名前がベジータ、技がファイナルフラッシュ

というように、同じ設計図から違う個性を持つ存在として扱えるようになります。

イメージを表にするとこうなります。

オブジェクト名前
悟空悟空かめはめ波
ベジータベジータファイナルフラッシュ

ここで大切なのは、どちらも同じサイヤ人クラスから作られているということです。
つまり、同じ型を土台にしながら、それぞれに別の情報を持たせられるのがオブジェクトの強みです。

オブジェクトができると、具体的な情報を持たせられる

クラスの段階では、名前や戦闘力という「項目」しかありません。
でもオブジェクトを作ると、その項目に具体的な値を入れられるようになります。

たとえば、サイヤ人クラスに

  • 名前
  • 戦闘力

というフィールドがあったとします。
そのとき、悟空のオブジェクトには、

  • 名前 = 悟空
  • 戦闘力 = 高い値
  • 技 = かめはめ波

のような内容を持たせられます。

ベジータのオブジェクトには、

  • 名前 = ベジータ
  • 戦闘力 = 別の値
  • 技 = ファイナルフラッシュ

のようにできます。

つまりクラスが「何を持てるか」を決めて、オブジェクトが「実際に何を持っているか」を表すわけです。

この違いはとても大切です。

役割意味
クラス持てる情報の種類を決める
オブジェクト実際の具体的な値を持つ

クラスとオブジェクトの関係を整理する

ここで、クラスとオブジェクトの関係を一度しっかり整理しておきましょう。

項目クラスオブジェクト
役割設計図実体
サイヤ人悟空、ベジータ、悟飯
状態共通ルールだけ持つ具体的な値を持つ
使い方どんな情報や機能があるか決める実際に情報を持たせて動かす

この表の感覚がつかめると、オブジェクト指向の入口がかなりわかりやすくなります。

特に、
クラスは説明書、オブジェクトは実際の登場人物
という感覚を持てると理解が深まります。

イメージコードで流れを確認する

ここまでの内容を、ドラゴンボールのたとえに合わせたイメージコードで整理してみます。

class サイヤ人
{
    名前;
    戦闘力;
    技;
}

このクラスは、サイヤ人が持つ情報の設計図です。

次に、このクラスから実体を作ります。

サイヤ人 悟空;
悟空 = new サイヤ人();

または、1行にまとめるならこうです。

サイヤ人 悟空 = new サイヤ人();

さらに複数作るならこうなります。

サイヤ人 悟空 = new サイヤ人();
サイヤ人 ベジータ = new サイヤ人();
サイヤ人 悟飯 = new サイヤ人();

これで、サイヤ人クラスという1つの設計図から、複数の実体を作れることが見えてきます。

図で見ると、設計図と実体の違いがわかりやすい

この図では、左にあるサイヤ人クラスが設計図です。
ここには、どんな情報を持てるかだけが書かれています。

そこから右側に向かって、悟空、ベジータ、悟飯という3つのオブジェクトが作られています。
この3つは同じ設計図から作られていますが、中に入る具体的な値は違います。

この見方ができるようになると、
「クラスは1つでも、オブジェクトは何個も作れる」
という感覚がかなり自然になります。

変数がオブジェクトを扱えるようになる、という感覚

もうひとつ大切なのが、変数がオブジェクトを扱えるようになる、という感覚です。

サイヤ人 悟空 = new サイヤ人();

この文では、悟空という変数が、new で作られたサイヤ人オブジェクトを扱えるようになります。

ここで意識したいのは、変数そのものが戦士になったわけではなく、変数を通してそのオブジェクトに触れられるようになったということです。

ドラゴンボールでいえば、悟空という名札をつけた枠を通して、その実体を操作できるようになった感じです。

この感覚は、このあとフィールドに値を入れたり、メソッドを呼び出したりするときにとても大切になります。

いちばん大事な感覚

「クラスから実体を作る仕組み」でいちばん大切なのは、次の流れです。

  • クラスは設計図
  • オブジェクトは設計図から作られた実体
  • 実体を使うには、まず変数を用意する
  • new を使って実体を作る
  • 変数に代入すると、そのオブジェクトを扱えるようになる

ドラゴンボールで言いかえるなら、

  • サイヤ人という設計図を作る
  • その設計図から悟空やベジータという実体を生み出す
  • それぞれを別の存在として扱う

という流れです。

この感覚がしっかりつかめると、次に学ぶ「参照型の変数」や「メンバへのアクセス」もとても理解しやすくなります。クラスはただ書いて終わりではなく、そこから実体を作ってはじめて、プログラムの中で本当に使えるようになるのです。