Interfaceは美味しいのです！！

# オブジェクト指向を語る上で「Interface」が軽視されているように感じます
まず下記の[ソースコード](#サンプルコード)を読んで頂いてから本文を読んで頂き、ご指摘を頂ければ幸いです。

## 今回の投稿をした経緯
「Interfaceって美味しいの?」と言わんばかりの設計・実装が多く、
「Interfaceは美味しいんだ」と言いたくて記事にしてみました

## 設計方針
### 1.　なぜ自分はInterfaceが必要なのか考えた理由
1.1　処理のInputとOutputはハッキリさせたい（チームで作業するなら制約として必要）
1.2　Interfaceで作成する事によってメンバ変数にアクセスさせない
1.3　オブジェクト内部の状態は隠蔽してクラスとメソッドの役割をハッキリさせたい

### 2.　なぜHumanクラスだけAbstractClassでなぜDogクラスとTurtleクラスにも適用出来るAbstractClassを作成しなかったのか
2.1　BabyクラスもOldManクラスもHumanクラスとis a関係だからです。
2.1.1　簡単に説明すると赤ん坊も人だし、ビジネスマンも人だからです。
2.1.2　BabyクラスもOldManクラスもDogクラスも哺乳類という意味ではis a関係ですが、IMoveインターフェースではThrowメソッドが存在します。
2.1.3　犬が物を投げる事が出来ないのだから哺乳類という括りではAbstractClassを作成しませんでした。
2.1.4　DogクラスとTurtleクラスのAbstractClassを作成しないのか共通のis a関係が自分の中では見つからなかったからです。

##サンプルコード
テーマは歩く等です

```csharp:main.cs
void Main()
{
	IMove iMove = MoveFactory.CreateInstance(MoveFactory.Category.OldMan);
	try
	{
		var numberOfStep = iMove.Wolk();
		var longCastDistance = iMove.Throw();
		Console.WriteLine(string.Format("歩数:{0}", numberOfStep));
		Console.WriteLine(string.Format("遠投距離:{0}", longCastDistance));
	}
	catch (NotSupportedException ex)
	{
		Console.WriteLine(string.Format("ｻﾎﾟｰﾄ対象外:{0}", ex.Message));
	}
	catch (Exception ex)
	{
		Console.WriteLine(string.Format("想定外例外:{0}", ex.Message));
	}
}
```

```csharp:IMove.cs
public interface IMove
{
	int Wolk();
	int Throw();
}
```

```csharp:MoveFactory.cs
public static class MoveFactory
{
	public enum Category
	{
		Unknown = 0,
		OldMan = 1,
		Baby = 2,
		Dog = 3,
		Turtle = 4
	}

	public static IMove CreateInstance(Category category)
	{
		switch (category)
		{
			case Category.Baby:
				return new Baby();
			case Category.OldMan:
				return new OldMan();
			case Category.Dog:
				return new Dog();
			case Category.Turtle:
				return new Turtle();
		}
		
		return null;
	}
}
```

```csharp:Human.cs
public abstract class Human : IMove
{
	// 足の数
	protected virtual int LegNum
	{
		get { return 2; }
	}

	protected virtual int Stride
	{
		get { return 3; }
	}

	// 腕の数
	protected virtual int ArmNum
	{
		get { return 2; }
	}

	protected virtual int Power
	{
		get { return 3; }
	}

	public virtual int Wolk()
	{
		return LegNum * Stride;
	}

	public virtual int Throw()
	{
		return ArmNum * Power;
	}
}
```

```csharp:Baby.cs
public class Baby : Human
{
	protected override int LegNum
	{
		get { return 4; }
	}

	protected override int Stride
	{
		get { return 1; }
	}

	protected override int Power
	{
		get { return 1; }
	}

	// 小数点は切り捨て
	public override int Wolk()
	{
		return LegNum * Stride / 4;
	}

	// 動作は投げているが、落としているに近い為
	public override int Throw()
	{
		return ArmNum * Power * 0;
	}
}
```

```csharp:OldMan.cs
public class OldMan : Human
{
	protected override int Stride
	{
		get { return 2; }
	}

	protected override int Power
	{
		get { return 2; }
	}

	// 小数点は切り捨て
	public override int Wolk()
	{
		return LegNum * Stride / 2;
	}
}
```

```csharp:Dog.cs
public class Dog : IMove
{
	protected int LegNum
	{
		get { return 4; }
	}

	protected int Stride
	{
		get { return 4; }
	}

	public int Wolk()
	{
		return LegNum * Stride;
	}

	public int Throw()
	{
		throw new NotSupportedException("Dogは投げれません");
	}
}
```

```csharp:Turtle.cs
public class Turtle : IMove
{
	protected int LegNum
	{
		get { return 4; }
	}

	protected int Stride
	{
		get { return 1; }
	}

	public int Wolk()
	{
		return LegNum * Stride;
	}

	public int Throw()
	{
		throw new NotSupportedException("Turtleは投げれません");
	}
}
```