【C#】オブジェクト指向（クラスとオブジェクト）

●はじめに

　こんにちは。
　今回は、プログラミングするうえでは避けては通れないオブジェクト指向について説明をしていきたいと思います。
　私も初めて見たときは癖があって理解するのに時間がかかりましたがわかりやすく解説していきます。

「え、そもそもC#とか初めてなんだけど。。。」
「プログラミングの基礎がわからない。」

という方向けの記事ではないので以下のサイトの基本編を学んでからこの記事を読んでください。
[→一週間で身につくC#言語の基本](https://csharp.sevendays-study.com/)

「C#の配列変数くらいまでならできるよー」
って方でオブジェクト指向につまずいている方は是非、読んでください。
　

●オブジェクト指向の考え方
　オブジェクト指向とは、あらゆるものを、すべて「モノ」として表現する考え方のことを言います。オブジェクト指向のオブジェクト(Object)とは、英語で「モノ」を表す言葉です。
　例えば、自動車を運転する際には、自動車内部の仕組みを理解する必要はありません。ただ運転方法だけを知っていれば、それだけで自動車を使うことができます。つまり、「自動車」というオブジェクトは、動作させる仕組みがすでに内部に組み込まれていることから、それを利用するためには、仕組みを知る必要は一切なく、ただアクセルを踏む、、ハンドルを切るなどといったような適切な操作をすればよいことになります。
　オブジェクトには、操作にあたる**メソッド**と呼ばれる部分と、データに当たる**フィールド**があります。自動車の例でいえば、「発信する」「停止する」などがメソッドで、「スピード」「走行距離」がフィールドといったところでしょう。

・自動車オブジェクトのフィールドとメソッド
| フィールド／メソッド | 対象 |
|:-:|:-:|
| メソッド  | 発信する  |
| メソッド  | 停止する  |
| メソッド  | 曲がる  |
| フィールド  | スピード  |
| フィールド  | 走行距離  |
| フィールド  | 排気量  |

　
●クラスとオブジェクト
　C#でオブジェクト指向を利用するためには、さらに**クラス（class）** という概念について理解する必要があります。
　先ほどの自動車という例を用いて説明すると、世の中には自動車がたくさん存在します。ただ、たくさんある自動車も、１つの設計図をもとに大量生産されているはずです。この**設計図に当たるものがクラス**です。設計図であるクラスをもとに生産された実体がオブジェクトであり、英語で「実例」を意味するインスタンス（Instance）とも呼びます。
　つまり、クラスがなければ、オブジェクトもありません。以上が、基本的なオブジェクト指向の考え方です。オブジェクト指向には、この他にさまざまな概念がありますが、機会があれば紹介していきます。
　
　
●なぜオブジェクト指向が必要なのか
　このような説明を聞くと「なんでそんな複雑な概念が必要になるのだろう」と疑問に思われる方も少なくないでしょう。しかし、このオブジェクト指向は初めて見る方には一見めんどくさそうに見えるのですが、きちんと活用すると、ソフトウェア開発をより効率的にしてくれます。
　例えば、ウォー・シミュレーションゲームを作っているときに、同じ「乗り物」でも、「戦闘機」と「ヘリコプター」では処理が違ってくるはずです。通常、ゲームのようなソフトウェア開発は非常に規模が大きいため、多数のプログラマーが開発に参加しています。そして「Aさんは戦闘機の処理を担当」「Bさんはヘリコプターの処理を担当」といった具合に役割分担します。その際、オブジェクト指向言語でプログラムをすれば、**言語仕様で「戦闘機クラス」と「ヘリコプタークラス」というように担当を分ける**ことができるため、役割分担が非常に楽になり、開発効率がアップします。
　つまり、オブジェクト指向言語というのは、このような大規模開発が必要となるような、時代のニーズにマッチしたプログラミング言語だといえるのです。
　
　
●簡単なオブジェクト指向のサンプル
　では、ここで実際に、C#によるオブジェクト指向のプログラムの実例を見てみることにしましょう。C#やJavaのようなオブジェクト指向の言語は、原則的にあらゆるものをクラスとして定義します。「設計図」という言い方をすると機械のようなものだけに想像されるかもしれませんが、実際は人間、動物、抽象的な概念など、あらゆる「もの」をクラスとして定義します。
　例えば住所録のようなものを作る場合は、あらゆる「人」クラスを定義し、そこに名前や年齢といったフィールドを定義し、その情報を取得・登録するメソッドがを定義します。
　そしてそのクラスを使って山田太郎さん、佐藤花子さんといった特定の人物のインスタンスを作成します。
　では実際に、どのようにしてそのような記述をするのかを簡単なサンプルを通してみてみることにしましょう。Person.csとProgram.csに以下のように入力してください。
　
※C#を座学で学んだけど、プログラムを実行したことがない方は以下の記事を参考にしてください
[→【C#】Visual Studio 2022をインストールする手順を紹介](https://marunaka-blog.com/c-sharp-visual-studio-2022-install/6348/)
　ちなみにC#はアップデートによるソースコード変更が激しいので最新版の開発環境だとソースコード仕様が違う可能性があります。私はVisual Studio 2019をインストールしています。
　
　
```C#:Person.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test_CS
{
    class Person
    {
        // 名前（フィールド）
        public string name = "";
        // 年齢（フィールド）
        public int age = 0;
        // 情報の表示（メソッド）
        public void ShowAgeAndName()
        {
            Console.WriteLine("名前:{0} 年齢:{1}", name, age);
        }
        // 情報の設定
        public void SetAgeAndName(string name, int age)
        {
            this.name = name;
            this.age = age;
        }
    }
}
```

```C#:Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test_CS
{
    class Program
    {
        static void Main(string[] args)
        {
            Person p1, p2;
            // 1つ目のPersonクラスのメソッドのインスタンスを生成
            p1 = new Person();
            // 2つ目のPersonクラスのメソッドのインスタンスを生成
            p2 = new Person();
            p1.name = "山田太郎"; // フィールドnameに値を代入
            p1.age = 19; // フィールドageに値を代入
            // メソッドでnameとageを設定
            p2.SetAgeAndName("佐藤花子", 23);
            // それぞのインスタンスnameとageを表示
            p1.ShowAgeAndName();
            p2.ShowAgeAndName();
        }
    }
}
```

```C#:実行結果
名前:山田太郎 年齢:19
名前:佐藤花子 年齢:23
```
　
●クラスの仕組み
　Person.csでは、個人の名前と年齢を扱うPersonクラスを定義しています。クラスの定義は以下のように記述します。
```C#:
class クラス名
{
    フィールド／メソッドの定義
}
```
　今回はPersonクラスというクラスを定義しているので、この処理は「class Person」という記述から始まります。この中に、フィールドとメソッドを定義します。すでに説明した通り、フィールドとはこのクラス内で持ちうる変数であり、メソッドはこのクラス内で定義できるさまざまな処理に名前を付けたものです。
　なおC#では慣習的に、**クラス名とファイル名を同じにします**。この例ではPersonというクラスを定義しているので、ファイル名はPerson.csとなります。
　
　
●インスタンスの生成
　クラスは定義しただけでは使えません。原則的にクラスに定義されたさまざまな処理を実行するためには、このクラスをもとにインスタンスを生成する必要があります。インスタンスを生成すればクラス内で定義されたフィールドおよびメソッドが使用可能になります。
　クラスのインスタンスを生成している箇所です。

```C#:クラスのインスタンスを生成している箇所
// 1つ目のPersonクラスのメソッドのインスタンスを生成
p1 = new Person();
// 2つ目のPersonクラスのメソッドのインスタンスを生成
p2 = new Person();
```
　これにより、**変数p1とp2は、Personクラスのインスタンスを参照**します。
　人が違うと名前や年齢が異なるように、Personクラス内で定義されているフィールドであるnameやageは同一のフィールド名であるにもかかわらず、**インスタンスごとに違う値を持ちます。**
 また、AさんとBさんという2人の人物がいたとき、AさんもBさんも「歩く」という動作をすることはできますが、Aさんが歩いたからといって、Bさんまで歩き始めることはありません。
　それと同じで、インスタンスの動作を表すメソッドは、**メソッドが実行されたインスタンスのみに影響を与えます。**
　ちなみに筆者はこのインスタンス生成によってダンジョンRPGの多数の敵キャラを作って楽しんでいました。敵キャラに「HP」「攻撃」「防御」のステータスを持たせ、各敵キャラのパラメータを変更してインスタンスを作っていました。

　説明が長くなるので続きの解説は次回に回します。
　

【投稿者】
エンジニアファーストの会社 [株式会社CRE-CO](https://www.cre-co.jp/#top)　田渕浩之

【参考文献】
[→1週間でC#の基礎が学べる本](https://www.amazon.co.jp/1%E9%80%B1%E9%96%93%E3%81%A7C-%E3%81%AE%E5%9F%BA%E7%A4%8E%E3%81%8C%E5%AD%A6%E3%81%B9%E3%82%8B%E6%9C%AC-1%E9%80%B1%E9%96%93%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E4%BA%80%E7%94%B0-%E5%81%A5%E5%8F%B8/dp/4295007331/ref=sr_1_20?qid=1687129207&refinements=p_n_feature_seven_browse-bin%3A3332747051&s=books&sr=1-20)