【C++】Interface(デザインパターン)

## Interfaceとは?
**クラスが提供すべき機能の集合を
純粋仮想関数で構成する**設計。
- 異なるクラスが同じインターフェースを実装することで、**多態性が実現**できる
- クラス間の依存関係を緩くし、**柔軟性を高める**
- 共通の機能をカプセル化し、**複数のクラスで再利用**できる

### C++
```C++:Interface.cpp
#include <iostream>
#include <string>
#include <format>

/// <summary>
/// Unityのライフサイクル用のインターフェース
/// (上位インターフェース)
/// </summary>
class LifeCycleInterface
{
public:
	inline virtual void Start(void) = 0;
	inline virtual void Update(void) = 0;
	inline virtual void Draw(void) = 0;

	struct Vector3
	{
		float x,
			y,
			z;
	};
};

/// <summary>
/// キャラクター用のインターフェース
/// (下位インターフェース)
/// </summary>
class CharacterInterface
	: public LifeCycleInterface
{
public:
	inline virtual void Attack(void) = 0;
	inline virtual void Guard(int _atk) = 0;
	inline virtual void Heal(void) = 0;

	inline virtual int GetAtk(void) const = 0;

	struct Status
	{
		int hp,
			atk,
			def;
	};
};

/// <summary>
/// プレイヤー
/// </summary>
class Player
	: public CharacterInterface
{
public:
	Player() = default;
	virtual ~Player() = default;

	inline virtual void Start(void) override
	{
		position = { 0, 0, 0 };
		status = { 3,2,1 };
		std::cout << "ステータスが初期化されました" << std::endl;
	}
	inline virtual void Update(void) override { /*更新処理*/ }
	inline virtual void Draw(void) override { /*描画処理*/ }

	inline virtual void Attack(void) override
	{
		std::cout << "プレイヤーの攻撃!" << std::endl;
	}
	inline virtual void Guard(int _atk) override
	{
		std::cout << std::format("プレイヤーは{}のダメージ!!", _atk - status.def) << std::endl;
	}
	inline virtual void Heal(void) override
	{
		status.hp++;
		std::cout << "プレイヤーは1回復した!" << std::endl;
	}

	inline virtual int GetAtk(void) const override { return status.atk; }

private:
	Vector3 position = { 0,0,0 };
	Status status = { 0,0,0 };
};

/// <summary>
/// 敵
/// </summary>
class Enemy
	: public CharacterInterface
{
public:
	Enemy() = default;
	virtual ~Enemy() = default;

	inline virtual void Start(void) override
	{
		position = { 0, 0, 0 };
		status = { 2,1,0 };
		std::cout << "ステータスが初期化されました" << std::endl;
	}
	inline virtual void Update(void) override { /*更新処理*/ }
	inline virtual void Draw(void) override { /*描画処理*/ }

	inline virtual void Attack(void) override
	{
		std::cout << "敵の攻撃!" << std::endl;
	}
	inline virtual void Guard(int _atk) override
	{
		std::cout << std::format("敵は{}のダメージ!!", _atk - status.def) << std::endl;
	}
	inline virtual void Heal(void) override
	{
		status.hp++;
		std::cout << "敵は1回復した!" << std::endl;
	}

	inline virtual int GetAtk(void) const override { return status.atk; }

private:
	Vector3 position = { 0,0,0 };
	Status status = { 0,0,0 };
};

int main(void)
{
	Player p;
	Enemy e;

	// インターフェイスをアップキャストして格納
	CharacterInterface* pPlayer = &p;
	CharacterInterface* pEnemy = &e;

	pPlayer->Start();
	pEnemy->Start();

	pPlayer->Attack();
	pEnemy->Guard(pPlayer->GetAtk());
	pEnemy->Attack();
	pPlayer->Guard(pEnemy->GetAtk());
	pPlayer->Heal();
	pEnemy->Heal();

	return 0;
}
```

### C#
```C#:Interface.cs
using System;

/// <summary>
/// Unityのライフサイクル用のインターフェース
/// (上位インターフェース)
/// </summary>
public abstract class LifeCycleInterface
{
    public struct Vector3
    {
        public float x,
            y,
            z;

        public Vector3(float _x, float _y, float _z)
        {
            x = _x;
            y = _y;
            z = _z;
        }
    };

    public abstract void Start();
    public abstract void Update();
    public abstract void Draw();
}

/// <summary>
/// キャラクター用のインターフェース
/// (下位インターフェース)
/// </summary>
public abstract class CharacterInterface : LifeCycleInterface
{
    public struct Status
    {
        public int hp,
            atk,
            def;

        public Status(int _hp, int _atk, int _def)
        {
            hp = _hp;
            atk = _atk;
            def = _def;
        }
    };

    public abstract void Attack();
    public abstract void Guard(int _atk);
    public abstract void Heal();

    public abstract int GetAtk { get; }
}

/// <summary>
/// プレイヤー
/// </summary>
public class Player : CharacterInterface
{
    private Vector3 position = new Vector3(0, 0, 0);
    private Status status = new Status(0, 0, 0);

    public override void Start()
    {
        position = new Vector3(0, 0, 0);
        status = new Status(3, 2, 1);
        Console.WriteLine("ステータスが初期化されました");
    }
    public override void Update() { /*更新処理*/ }
    public override void Draw() { /*描画処理*/ }

    public override void Attack() { Console.WriteLine("プレイヤーの攻撃!"); }
    public override void Guard(int _atk)
    {
        Console.WriteLine($"プレイヤーは{_atk - status.def}のダメージ!!");
    }
    public override void Heal()
    {
        status.hp++;
        Console.WriteLine("プレイヤーは1回復した!");
    }

    public override int GetAtk { get { return status.atk; } }
}

/// <summary>
/// 敵
/// </summary>
public class Enemy : CharacterInterface
{
    private Vector3 position;
    private Status status;

    public override void Start()
    {
        position = new Vector3(0, 0, 0);
        status = new Status(2, 1, 0);
        Console.WriteLine("ステータスが初期化されました");
    }
    public override void Update() { /*更新処理*/ }
    public override void Draw() { /*描画処理*/ }

    public override void Attack() { Console.WriteLine("敵の攻撃!"); }
    public override void Guard(int _atk)
    {
        Console.WriteLine($"敵は{_atk - status.def}のダメージ!!");
    }
    public override void Heal()
    {
        status.hp++;
        Console.WriteLine("敵は1回復した!");
    }

    public override int GetAtk { get { return status.atk; } }
};

public class Program
{
    static void Main()
    {
        Player player = new Player();
        Enemy enemy = new Enemy();

        player.Start();
        enemy.Start();

        player.Attack();
        enemy.Guard(player.GetAtk);
        enemy.Attack();
        player.Guard(enemy.GetAtk);
        player.Heal();
        enemy.Heal();
    }
}
```

#### 追記
C#にはinterface型があったらしい...
何だったのか、俺の努力は...

```C#:Interface.cs
using System;

/// <summary>
/// Unityのライフサイクル用のインターフェース
/// (上位インターフェース)
/// </summary>
public interface LifeCycleInterface
{
    void Start();
    void Update();
    void Draw();
}

/// <summary>
/// キャラクター用のインターフェース
/// (下位インターフェース)
/// </summary>
public interface CharacterInterface : LifeCycleInterface
{
    void Attack();
    void Guard(int attackPower);
    void Heal();

    int GetAtk { get; }
}

/// <summary>
/// プレイヤー
/// </summary>
public class Player : CharacterInterface
{
    public struct Vector3
    {
        public float x,
            y,
            z;

        public Vector3(float _x, float _y, float _z)
        {
            x = _x;
            y = _y;
            z = _z;
        }
    };
    private Vector3 position = new Vector3(0, 0, 0);

    public struct Status
    {
        public int hp,
            atk,
            def;

        public Status(int _hp, int _atk, int _def)
        {
            hp = _hp;
            atk = _atk;
            def = _def;
        }
    };
    private Status status = new Status(0, 0, 0);

    public virtual void Start()
    {
        position = new Vector3(0, 0, 0);
        status = new Status(3, 2, 1);
        Console.WriteLine("ステータスが初期化されました");
    }
    public virtual void Update() { /*更新処理*/ }
    public virtual void Draw() { /*描画処理*/ }

    public virtual void Attack() { Console.WriteLine("プレイヤーの攻撃!"); }
    public virtual void Guard(int _atk)
    {
        Console.WriteLine($"プレイヤーは{_atk - status.def}のダメージ!!");
    }
    public virtual void Heal()
    {
        status.hp++;
        Console.WriteLine("プレイヤーは1回復した!");
    }

    public virtual int GetAtk { get { return status.atk; } }
}

/// <summary>
/// 敵
/// </summary>
public class Enemy : CharacterInterface
{
    public struct Vector3
    {
        public float x,
            y,
            z;

        public Vector3(float _x, float _y, float _z)
        {
            x = _x;
            y = _y;
            z = _z;
        }
    };
    private Vector3 position = new Vector3(0, 0, 0);

    public struct Status
    {
        public int hp,
            atk,
            def;

        public Status(int _hp, int _atk, int _def)
        {
            hp = _hp;
            atk = _atk;
            def = _def;
        }
    };
    private Status status = new Status(0, 0, 0);

    public virtual void Start()
    {
        position = new Vector3(0, 0, 0);
        status = new Status(2, 1, 0);
        Console.WriteLine("ステータスが初期化されました");
    }
    public virtual void Update() { /*更新処理*/ }
    public virtual void Draw() { /*描画処理*/ }

    public virtual void Attack() { Console.WriteLine("敵の攻撃!"); }
    public virtual void Guard(int _atk)
    {
        Console.WriteLine($"敵は{_atk - status.def}のダメージ!!");
    }
    public virtual void Heal()
    {
        status.hp++;
        Console.WriteLine("敵は1回復した!");
    }

    public virtual int GetAtk { get { return status.atk; } }
};

public class Program
{
    static void Main()
    {
        Player player = new Player();
        Enemy enemy = new Enemy();

        player.Start();
        enemy.Start();

        player.Attack();
        enemy.Guard(player.GetAtk);
        enemy.Attack();
        player.Guard(enemy.GetAtk);
        player.Heal();
        enemy.Heal();
    }
}
```