Java道|Javaのクラスのしくみ

クラスが分かると、Javaのコードは「ただの処理」から「意味を持った部品」に変わる

Javaのクラスのしくみ

Javaを学び始めると、変数、配列、条件分岐、繰り返しなどを使って、少しずつプログラムを書けるようになります。最初のうちは、処理を上から順番に書くだけでも、簡単なプログラムなら十分に作れます。

しかし、プログラムで扱う内容が増えてくると、ただ処理を並べるだけでは分かりにくくなってきます。

たとえば、鬼滅の刃風の世界で考えてみましょう。

鬼殺隊士を管理するプログラムを作るとします。隊士には、名前があります。階級があります。使う呼吸があります。体力もあります。そして、攻撃する、移動する、状態を表示する、といった動きもあります。

これらをバラバラの変数や処理として書いていくと、隊士が増えたときにコードがどんどん複雑になります。

そこで登場するのがクラスです。

クラスは、関連する情報と動きをひとまとまりにするためのしくみです。Javaでは、このクラスがとても重要です。Javaのプログラムは基本的にクラスを土台にして作られているため、クラスの考え方を理解すると、Javaのコードが一気に見やすくなります。

鬼滅の刃風にたとえるなら、クラスは「鬼殺隊士を作るための設計図」です。

鬼殺隊士にはどんな情報が必要なのか。
鬼殺隊士はどんな動きができるのか。
それらをまとめて定義するものがクラスです。

ここでは、Javaのオブジェクト指向の入口として、クラス、フィールド、メソッド、メンバ、クラス宣言の基本を、鬼殺隊士の設計図としてイメージしながら整理していきます。

クラスは情報と動きをまとめるための設計図

Javaのクラスをひとことで表すと、あるものについての情報と動きをまとめた設計図です。

鬼滅の刃風に考えると、いきなり一人の隊士だけを考えるのではなく、まずは「鬼殺隊士という存在には、どんな情報があり、どんな動きがあるのか」を整理します。

鬼殺隊士には、たとえば次のような情報がありそうです。

項目
名前水月、雷斗、風牙
階級一般隊士、柱、見習い隊士
呼吸水の呼吸、雷の呼吸、風の呼吸
体力戦える残りの力
武器日輪刀、短刀、補助道具

また、情報だけでなく、次のような動きもあります。

動き
自己紹介する自分の名前や階級を名乗る
攻撃する呼吸を使って鬼に攻撃する
移動する戦場を走る、間合いを取る
状態を表示する名前、階級、呼吸、体力を表示する

このように、そのものが持っている情報と、そのものができる動きをひとつにまとめるのがクラスです。

クラスを使うと、ばらばらの変数や処理をそのまま並べるのではなく、

これは鬼殺隊士に関する情報
これは鬼殺隊士に関する動き
だから鬼殺隊士クラスにまとめる

というように、テーマごとに整理できます。

つまりクラスは、プログラムの中で扱うものを分かりやすく分類するための考え方でもあります。

Javaではクラスが土台になる

Javaでは、プログラムを書くときにクラスが欠かせません。

たとえば、Javaの基本的なコードは次のような形になります。

public class Main {
    public static void main(String[] args) {
        System.out.println("Javaを学習中です");
    }
}

この中の次の部分がクラスです。

public class Main

Javaを学び始めたばかりのころは、Main クラスを「とりあえず必要な外枠」と感じるかもしれません。

しかし、クラスをきちんと理解すると、この外枠にはもっと大切な意味があることが分かります。

クラスは、単なるコードの入れ物ではありません。
意味のある情報と処理をまとめる部品です。

鬼滅の刃風に言えば、クラスは「鬼殺隊士を登録して動かすための型」です。

たとえば、これまでは処理の流れを順番に書くことが中心だったかもしれません。しかしクラスを意識すると、次のような見方ができるようになります。

見方内容
どんな情報を持たせるか名前、階級、呼吸、体力など
どんな機能を持たせるか攻撃する、移動する、状態を表示するなど
どのまとまりで管理するか鬼殺隊士クラス、鬼クラス、任務クラスなど

この視点が、Javaのオブジェクト指向の入口です。

クラスとは何かを鬼滅の刃風で考える

鬼滅の刃風の世界には、さまざまな隊士がいます。

水の呼吸を使う隊士
雷の呼吸を使う隊士
風の呼吸を使う隊士
柱として任務を指揮する隊士

それぞれ個性は違いますが、共通して持っていそうな要素があります。

名前がある
階級がある
呼吸を使える
鬼と戦うことができる
自分の状態を示せる

こうした共通する情報と機能を整理して作る設計図がクラスです。

鬼殺隊士クラスのイメージ例

class 鬼殺隊士
{
    名前
    階級
    呼吸

    名前を決める
    攻撃する
    状態を表示する
}

これは、実際に動かすための厳密なJavaコードというより、クラスの考え方をつかむためのイメージです。

この中には、鬼殺隊士に関する情報と動きがまとまっています。

名前、階級、呼吸は、鬼殺隊士が持っている情報です。
名前を決める、攻撃する、状態を表示するは、鬼殺隊士ができる動きです。

このように、状態や性質と、それに関係する機能をひとつにまとめるのがクラスの役目です。

↓クリックすると拡大表示されます。

フィールドはそのものが持っている情報

クラスの中に書かれる情報の部分を、Javaではフィールドと呼びます。

フィールドは、そのものが持っている状態や性質を表します。

鬼滅の刃風に言えば、フィールドは鬼殺隊士のプロフィール欄です。

たとえば、鬼殺隊士クラスなら、次のようなフィールドが考えられます。

フィールド表している内容
名前隊士の名前
階級隊士としての立場
呼吸使う呼吸の種類
体力現在どれくらい戦えるか
武器持っている装備

鬼殺隊士のフィールドのイメージ例

class 鬼殺隊士
{
    名前
    階級
    呼吸
    体力
    武器
}

この5つはすべて、鬼殺隊士の情報です。

ここにはまだ、攻撃する、移動する、状態を表示するといった動きは書かれていません。あくまで、鬼殺隊士が持っている情報を保存する場所です。

フィールドを理解するときは、

その隊士の今の状態を覚えておくための欄

と考えると分かりやすいです。

たとえば、若い女性剣士の隊士なら、次のような情報を持っているイメージです。

項目内容
名前水月
階級一般隊士
呼吸水の呼吸
体力100
武器日輪刀

この情報をクラスの中で持たせるための場所がフィールドです。

Java風に近づけると、次のように書けます。

class DemonSlayer {
    String name;
    String rank;
    String breathingStyle;
    int stamina;
    String weapon;
}

この中の次の部分がフィールドです。

String name;
String rank;
String breathingStyle;
int stamina;
String weapon;

フィールドがあることで、1人の隊士に関する情報をひとまとまりとして扱えるようになります。

メソッドはそのものができる動き

クラスの中に書かれる機能の部分を、Javaではメソッドと呼びます。

フィールドが情報なら、メソッドは動きです。

鬼滅の刃風に言えば、メソッドは鬼殺隊士が実際に行う行動です。

たとえば、鬼殺隊士には次のようなメソッドが考えられます。

メソッド役割
名前を決める名前を設定する
攻撃する呼吸を使って鬼に攻撃する
移動する戦場を移動する
呼吸を使う技を発動する
状態を表示する現在の情報を表示する

鬼殺隊士のメソッドのイメージ例

class 鬼殺隊士
{
    名前
    階級
    呼吸
    体力

    名前を決める()
    {
        名前を設定する
    }

    攻撃する()
    {
        呼吸を使って鬼に攻撃する
    }

    移動する()
    {
        戦場を移動する
    }

    状態を表示する()
    {
        名前と階級と呼吸と体力を表示する
    }
}

ここで大切なのは、メソッドはクラスの外にあるばらばらの処理ではなく、そのクラスの情報に関係する動きとして書かれることです。

たとえば、状態を表示するという動きは、名前、階級、呼吸、体力と深く関係しています。だから、鬼殺隊士クラスの中に置くのが自然です。

Java風に書くと、次のようになります。

class DemonSlayer {
    String name;
    String rank;
    String breathingStyle;
    int stamina;

    void setName(String newName) {
        name = newName;
    }

    void attack() {
        System.out.println(name + "は" + breathingStyle + "で鬼に攻撃する");
    }

    void move() {
        System.out.println(name + "は戦場を素早く移動する");
    }

    void showStatus() {
        System.out.println("名前: " + name);
        System.out.println("階級: " + rank);
        System.out.println("呼吸: " + breathingStyle);
        System.out.println("体力: " + stamina);
    }
}

この中の次の部分がメソッドです。

void setName(String newName)
void attack()
void move()
void showStatus()

メソッドは、フィールドの情報を使って処理を行うことが多いです。

たとえば attack メソッドでは、name と breathingStyle を使っています。

void attack() {
    System.out.println(name + "は" + breathingStyle + "で鬼に攻撃する");
}

これは、隊士の名前と呼吸を使って、攻撃の内容を表示しています。

つまりメソッドは、クラスが持っている情報を使って、意味のある動きを実行する部分です。

図:クラスは情報と動きをまとめる設計図

↓クリックすると拡大表示されます。

この図が示していること

この図は、クラスの中にフィールドとメソッドが入っていることを示しています。

左側のフィールドは、鬼殺隊士が持っている情報です。名前、階級、呼吸、体力、武器のように、その隊士の状態や特徴を表します。

右側のメソッドは、鬼殺隊士ができる動きです。自己紹介する、攻撃する、移動する、呼吸を使う、状態を表示するというように、実際の行動を表します。

この図から分かることは、クラスは単なる情報の置き場ではなく、情報と動きをセットでまとめる設計図だということです。

フィールドとメソッドを合わせてメンバという

クラスの中にあるフィールドとメソッドは、まとめてメンバと呼ばれます。

メンバという言葉だけ見ると少しかたく感じるかもしれませんが、意味はとてもシンプルです。

クラスを構成している部品のことです。

用語役割
フィールド情報を持つ部品
メソッド動きを持つ部品
メンバフィールドとメソッドをまとめた呼び方

鬼殺隊士クラスなら、次のように整理できます。

種類
フィールドname、rank、breathingStyle、stamina
メソッドattack、move、showStatus
メンバフィールドとメソッドすべて

たとえば、次のクラスを見てみます。

class DemonSlayer {
    String name;
    String rank;
    String breathingStyle;

    void attack() {
        System.out.println(name + "は" + breathingStyle + "で鬼に攻撃する");
    }

    void showStatus() {
        System.out.println("名前: " + name);
        System.out.println("階級: " + rank);
        System.out.println("呼吸: " + breathingStyle);
    }
}

このクラスのメンバは、次のようになります。

メンバ種類
nameフィールド
rankフィールド
breathingStyleフィールド
attackメソッド
showStatusメソッド

このように、クラスの中にある情報と動きをまとめてメンバと呼びます。

Javaの説明で「このクラスのメンバ」という言葉が出てきたら、「クラスの中にあるフィールドやメソッドのこと」と考えると分かりやすいです。

クラスを宣言するとは何をしているのか

クラスを書くことを、Javaではクラスを宣言するといいます。

宣言という言葉は少しかたいですが、やっていることはシンプルです。

こういう情報を持つまとまりを作ります。
こういう機能を持つまとまりを作ります。
この名前のクラスとして定義します。

これがクラス宣言です。

鬼滅の刃風に言えば、

鬼殺隊士クラスを作ります。
このクラスには名前、階級、呼吸を持たせます。
さらに攻撃や状態表示の機能も持たせます。

と、設計図を作っている状態です。

鬼殺隊士のクラス宣言のイメージ例

class 鬼殺隊士
{
    名前
    階級
    呼吸

    攻撃する()
    {
        呼吸を使う
    }

    状態を表示する()
    {
        名前と階級と呼吸を表示する
    }
}

この段階では、まだ具体的な一人の隊士を作っているわけではありません。

「水月」という隊士を作っているのではなく、「鬼殺隊士という設計図」を用意している状態です。

ここで大切なのは、クラスはある一人だけの情報ではなく、共通の型を表すということです。

水月専用のその場限りのデータではなく、鬼殺隊士というまとまりを整理した土台を作っています。

Java風に書くと、次のようになります。

class DemonSlayer {
    String name;
    String rank;
    String breathingStyle;

    void attack() {
        System.out.println(name + "は" + breathingStyle + "で攻撃する");
    }

    void showStatus() {
        System.out.println("名前: " + name);
        System.out.println("階級: " + rank);
        System.out.println("呼吸: " + breathingStyle);
    }
}

この DemonSlayer クラスは、鬼殺隊士の共通の型です。

同じ設計図を使って、あとから水の呼吸の隊士、雷の呼吸の隊士、風の呼吸の隊士などを作れるようになります。

クラスは共通の型を表す

クラスを学ぶときに、とても大切な考え方があります。

それは、クラスは「具体的な一人」ではなく、「共通の型」を表すということです。

たとえば、DemonSlayer クラスは、特定の一人だけを表すものではありません。

水月だけの情報
雷斗だけの情報
風牙だけの情報

を直接書いているわけではなく、鬼殺隊士に共通する情報と動きをまとめています。

class DemonSlayer {
    String name;
    String rank;
    String breathingStyle;
}

このクラスは、いろいろな隊士に使えます。

隊士namerankbreathingStyle
水月水月一般隊士水の呼吸
雷斗雷斗一般隊士雷の呼吸
風牙風牙一般隊士風の呼吸

同じ DemonSlayer クラスでも、フィールドに入る値が変われば、別々の隊士を表せます。

つまりクラスは、具体的な値を入れる前の設計図です。

鬼滅の刃風に言えば、鬼殺隊士クラスは「隊士登録用の共通用紙」のようなものです。

名前欄
階級欄
呼吸欄

が用意されていて、そこに具体的な値を入れることで、1人ひとりの隊士を表せます。

なぜクラスが必要なのか

クラスが必要な理由は、プログラムを整理しやすくするためです。

もしクラスを使わずに、名前、階級、呼吸、体力、攻撃処理、表示処理をすべて別々に書いていたら、隊士が増えるたびに管理が大変になります。

たとえば、クラスを使わずに書くと、次のようになります。

String name1 = "水月";
String rank1 = "一般隊士";
String breathingStyle1 = "水の呼吸";

String name2 = "雷斗";
String rank2 = "一般隊士";
String breathingStyle2 = "雷の呼吸";

String name3 = "風牙";
String rank3 = "一般隊士";
String breathingStyle3 = "風の呼吸";

人数が少ないうちは、まだ読めます。

しかし、隊士が10人、20人、100人と増えていくと、どの名前が誰のものなのか、どの呼吸が誰のものなのかが分かりにくくなります。

さらに、攻撃処理や状態表示の処理も追加されると、コードはもっと複雑になります。

クラスを使えば、鬼殺隊士に必要な情報と動きをひとまとまりにできます。

class DemonSlayer {
    String name;
    String rank;
    String breathingStyle;

    void attack() {
        System.out.println(name + "は" + breathingStyle + "で鬼に攻撃する");
    }

    void showStatus() {
        System.out.println("名前: " + name);
        System.out.println("階級: " + rank);
        System.out.println("呼吸: " + breathingStyle);
    }
}

このようにしておけば、鬼殺隊士に関係する情報と動きが DemonSlayer クラスにまとまります。

クラスを使うメリットは次のとおりです。

メリット説明
情報をまとめられる名前、階級、呼吸などを1つのまとまりにできる
動きをまとめられる攻撃、移動、状態表示などを一緒に管理できる
コードが読みやすくなる何についての処理なのか分かりやすい
修正しやすくなる変更する場所を見つけやすい
同じ型を使い回せる複数の隊士を同じ設計図から作れる

クラスは、プログラムが大きくなったときほど力を発揮します。

鬼殺隊の隊士が増えても、DemonSlayer という共通の設計図があれば、情報と動きを整理しながら扱えます。

クラスを見るときのコツ

クラスの学び始めで迷いやすいのは、クラスの中にいろいろ書かれていて、何が何だか分からなくなることです。

そんなときは、次の順番で見ると理解しやすいです。

見る順番確認すること鬼滅の刃風の見方
1何についてのクラスか鬼殺隊士についての設計図か
2どんな情報を持つか名前、階級、呼吸、体力など
3どんな動きをするか攻撃する、移動する、状態を表示するなど

たとえば、次のクラスを見てみます。

class DemonSlayer {
    String name;
    String rank;
    String breathingStyle;

    void attack() {
        System.out.println(name + "は" + breathingStyle + "で鬼に攻撃する");
    }

    void showStatus() {
        System.out.println("名前: " + name);
        System.out.println("階級: " + rank);
        System.out.println("呼吸: " + breathingStyle);
    }
}

まず見るのは、クラス名です。

class DemonSlayer

これで、鬼殺隊士についてのクラスだと分かります。

次にフィールドを見ます。

String name;
String rank;
String breathingStyle;

これで、このクラスは名前、階級、呼吸を情報として持つことが分かります。

最後にメソッドを見ます。

void attack()
void showStatus()

これで、このクラスは攻撃する、状態を表示するという動きを持つことが分かります。

この順番で見ると、クラスの中身がかなり整理しやすくなります。

図:クラス宣言は鬼殺隊士の設計図を作ること

↓クリックすると拡大表示されます。

この図が示していること

この図は、クラス宣言が「具体的な一人を作ること」ではなく、「共通の設計図を作ること」だと示しています。

巻物の中にある名前、階級、呼吸は、鬼殺隊士が持つ情報です。
攻撃する、移動する、状態を表示するは、鬼殺隊士ができる動きです。

そして、その設計図から複数の隊士アイコンが生まれていることで、同じクラスから複数の実体を作れることを表しています。

この図から分かることは、クラスは1回作って終わりではなく、いろいろな値を入れて使い回せる共通の型だということです。

クラスの基本構造をイメージコードで整理する

ここまでの内容を、ひとつのイメージコードとして整理してみます。

鬼殺隊士クラスの基本構造のイメージ例

class 鬼殺隊士
{
    名前
    階級
    呼吸
    体力
    武器

    名前を決める()
    {
        名前を設定する
    }

    階級を決める()
    {
        階級を設定する
    }

    呼吸を決める()
    {
        呼吸を設定する
    }

    攻撃する()
    {
        呼吸を使って鬼に攻撃する
    }

    移動する()
    {
        戦場を移動する
    }

    状態を表示する()
    {
        名前を表示する
        階級を表示する
        呼吸を表示する
        体力を表示する
        武器を表示する
    }
}

この形を見ると、クラスの基本がよく分かります。

上のほうには情報がまとまっています。

名前
階級
呼吸
体力
武器

下のほうには動きがまとまっています。

名前を決める
階級を決める
呼吸を決める
攻撃する
移動する
状態を表示する

そして、どちらも鬼殺隊士に関係する内容だけでそろっています。

これが大切です。

クラスの中に何でも入れてよいわけではありません。
鬼殺隊士クラスなら、鬼殺隊士に関係する情報と動きを入れます。

そうすることで、コードが読みやすくなり、あとから手を加えるときも整理しやすくなります。

Java風の基本構造

イメージコードをJava風に書くと、次のようになります。

class DemonSlayer {
    String name;
    String rank;
    String breathingStyle;
    int stamina;
    String weapon;

    void setName(String newName) {
        name = newName;
    }

    void setRank(String newRank) {
        rank = newRank;
    }

    void setBreathingStyle(String newBreathingStyle) {
        breathingStyle = newBreathingStyle;
    }

    void attack() {
        System.out.println(name + "は" + breathingStyle + "で鬼に攻撃する");
    }

    void move() {
        System.out.println(name + "は戦場を移動する");
    }

    void showStatus() {
        System.out.println("名前: " + name);
        System.out.println("階級: " + rank);
        System.out.println("呼吸: " + breathingStyle);
        System.out.println("体力: " + stamina);
        System.out.println("武器: " + weapon);
    }
}

このコードでは、DemonSlayer クラスの中に、フィールドとメソッドがまとまっています。

区分内容
フィールドname、rank、breathingStyle、stamina、weapon
メソッドsetName、setRank、setBreathingStyle、attack、move、showStatus

フィールドは、鬼殺隊士の情報です。
メソッドは、鬼殺隊士の動きです。

この2つをひとつのクラスにまとめることで、鬼殺隊士に関するコードとして整理できます。

クラスを学ぶ最初の段階で大切なこと

クラスを学ぶ最初の段階では、いきなり難しい用語をすべて完璧に覚えようとしなくても大丈夫です。

まずは、次の考え方をしっかりつかむことが大切です。

クラスは、情報と動きをひとまとめにするしくみです。
情報はフィールドです。
動きはメソッドです。
フィールドとメソッドをまとめてメンバと呼びます。
クラスを宣言するとは、その設計図を作ることです。

鬼滅の刃風に考えるなら、クラスとは「鬼殺隊士の設計図」を作ることです。

その設計図の中に、名前や階級や呼吸のような情報があります。
攻撃する、移動する、状態を表示するという動きもあります。
それらをひとつの部品として整理していくのが、Javaのクラスの基本です。

この感覚を持てるようになると、これから先のオブジェクト指向の学習がかなり進めやすくなります。