オブジェクト指向をC#のサンプルコードと一緒に勉強してみた

#1.はじめに
業務ではC#を使ってましたが、オブジェクト指向がどういうものか理解していない部分もあるので、調べたことや学習したことをまとめてみました。

#2.オブジェクト指向と手続き型
まずはざっくりオブジェクト指向がどういうものか例を挙げてみます。ここでは、手続き型と対比させてみます。
単語を調べると以下のような意味です。

オブジェクト指向:モノごとにまとめて動作する
手続き型:上から下という順番で動作する

手続き型はニュアンス的にはわかりますが、オブジェクト指向はイマイチピンときません。
ここで、「ステーキを作る」というプログラムを例にしてみます。

```:手続き型プログラミング
main {
 ステーキを作る
 肉買う
 味付け
 フライパンで焼く
}
```
```:オブジェクト指向
肉 {
  // 属性
  -値段
  -グラム

  // 機能
  焼く {  }
  蒸す {  }
}
牛肉.new()
ステーキ =牛肉.焼く()
```

手続き型プログラミングは定義と呼び出しによってプログラムを構造化してますが、オブジェクト指向ではテータと操作手続きのブロックを1つのオブジェクトとして考えます。

#3.サンプルプログラム概要
サンプルプログラムを使ってオブジェクト指向について説明します。
以下の処理は主人公がスライムを倒す処理です。

このサンプルプログラムは3つのクラスにわかれています。
Program.cs:メイン処理
Character.cs:RPGキャラクターのプロパティ、メソッドの設定している
PlayerCharacter.cs:Character.csを継承したクラス。

#4.キャラクタークラス
まずはCharacter.csを使ってクラス、メソッド、プロパティを解説していこうと思います。
キャラクターの情報（名前、レベル、HP、攻撃力）のやりとりをするクラスです。

```C#:Character.cs
class Character // クラス
{
    public string name; // 名前  プロパティ
    public int level;   // レベル プロパティ
    public int life;    // HP  プロパティ
    public int attack;  // 攻撃力  プロパティ
    public Character()
    {
        this.name = "";
        this.level = 1;
        this.life = 100;
        this.attack = 20;
    }

 public void setIntroduction(string setName = "", int setLevel = 0,int setLife = 0) // メソッド
    {
        if (setName != "")
        {
            name = setName;
        }
        if (setLevel != 0)
        {
            level = setLevel;
        }
        if (setLife != 0)
        {
            life = setLife;
        }
    }

    public void getDamege(int receivedDamege)// メソッド
    {     
        life -= receivedDamege;    // 受けたダメージだけHPを減らす
    }

    public int calcDamege()// メソッド
    {
        return attack; //攻撃力を返す
    }
}
```

###クラス
抽象化したオブジェクト（メソッド）をコード化したものです。Character.csでは、Characterクラスになります。メソッドとプロパティの塊です。


```C#
class Character // クラス
{
}
```
###メソッド
オブジェクトが持っている処理のことです。Character.csではsetIntroduction()やgetDamege()、calcDamege()など値を計算したり、受け渡す部分になります。

```C#
    public int calcDamege() // メソッド
    {
        return attack; //攻撃力を返す
    }
```

###プロパティ
クラスが持つ、オブジェクトを説明するデータのことです。Character.csでは名前、レベル、HP、攻撃力が該当します。

```C#
class Character
{
    public string name; // 名前  プロパティ
    public int level;   // レベル  プロパティ
    public int life;    // HP  プロパティ
    public int attack;  // 攻撃力  プロパティ
```

#5.プレイヤークラス
プレイヤー（主人公）の年齢、性別、経験値、職業を決めるクラスです。
このクラスを使って継承の説明をします。

```C#:PlayerCharacter.cs
class playerCharacter: Character
{
    public int age;
    public string sex;
    public int exp;
    public string job;
    public playerCharacter() : base()
    {
        this.age = 1;
        this.sex = "男";
        this.exp = 100;
        this.job = "むらびと";
    }

    public void setIntroduction(string setName = "", int setAge = 0, string setSex = "", string setJob = "", int setLife = 0)
    {
        if (setAge != 0)
        {
            age = setAge;
        }
        if (setSex != "")
        {
            sex = setSex;
        }
        if (setJob != "")
        {
            job = setJob;
        }
    }
}
```
###継承
子クラスが親クラスの特性を受け継ぐことです。
PlayerCharacter.csの名前、レベル、HPはCharacter.csにあるプロパティと共通しています。
また、calcDamege()やgetDamege()などメソッドもCharacter.csと同じものを使いたいです。このような場合に出てくるのが継承です。
Character.csのように継承元になるクラスを親クラス（スーパークラス）、PlayerCharacter.csのように引き継ぐクラスを子クラス（サブクラス）と呼びます。

```C#
class playerCharacter: Character
{
    public playerCharacter() : base() // 継承
    {
```
#6.メインクラス
プログラムの処理はここで書かれています。
このクラスを使って、インスタンス化の説明をします。

```C#:Program.cs
class Program
{
    static void Main(string[] args)
    {
        playerCharacter pc1;
        pc1 = new playerCharacter(); // インスタンス
        pc1.setIntroduction(setName: "山田太郎", setAge: 19,setLife:200);
        pc1.ShowDate(); 
        Enemy slime;
        slime = new Enemy();// インスタンス
        slime.setIntroduction(setName: "スライム", setExp: 200,setLife:100);

        while (slime.life > 0)
        {
            pc1.getDamege(receivedDamege: slime.calcDamege());
            Console.WriteLine("スライムの攻撃!" );     
            Console.WriteLine("PC1のHP：" + pc1.life);
            slime.getDamege(receivedDamege: pc1.calcDamege());
            Console.WriteLine("PCの攻撃!");
            Console.WriteLine("スライムのHP：" + slime.life);
        }      
        System.Console.WriteLine("{0}は{1}を倒した！", pc1.name,slime.name);
        pc1.calcLevel(calcExp: slime.giveExp);
    }
```

###インスタンス

クラスから生成される実体のことです。

```C#
        pc1 = new playerCharacter();
```
同じ名前のメソッドを使っていてもインスタンスごとに内容が違います。
setIntroduction（）は一番最初のキャラクターの情報を取得するメソッドです。


```C#
        pc1.setIntroduction(setName: "山田太郎", setAge: 19,setLife:200); //山田太郎の情報を取得する。
```

```C#
       slime.setIntroduction(setName: "スライム", setExp: 200,setLife:100); //スライムの情報を取得する。
```

#7.まとめ
今回でてきた用語の一覧です。
クラス:抽象化したオブジェクトのブロックをコード化したもの
プロパティ:クラスが持つ、オブジェクトを説明するデータ
継承:クラスが親クラスの特性を受け継ぐこと
メソッド:オブジェクトが持っている処理
インスタンス:クラスから生成された実体のこと

オブジェクト指向はなかなか理解するのは難しいと感じました。
自分でコードを書いたり、文章にするとわかりやすいと感じました。

#8.参考にしたサイト
初心者向けに徹底解説！オブジェクト指向とは？
https://eng-entrance.com/what-oop
オブジェクト指向とは？誰でもわかるようにやさしく解説
https://www.sejuku.net/blog/5973
【初心者必見】オブジェクト指向を分かりやすく解説
https://blog.codecamp.jp/object-orientation-explanation