オブジェクト指向
-多態性-

■多態性

多態性とはオブジェクト指向の概念の1つで、オブジェクト同士のやり取りで
同じメッセージ(関数)に対してオブジェクト毎に異なる対応をする性質のことです。
多様性ポリモーフィズムとも呼ばれています。

	pgtheory_0045

●最も単純な多態性
	最も単純な多態性の実現は各オブジェクト(クラス)に共通した関数を作成し、
	その関数を呼び出した際に各クラスで違った結果にすることです。

	例:
		class Shinji
		{
		public:
			// 挨拶
			void Greeting(void)
			{
				printf("お、おはよう\n");
			}
		};

		class Rei
		{
		public:
			// 挨拶
			void Greeting(void)
			{
				printf("…………\n");
			}
		};

		class Yui
		{
		public:
			// 挨拶
			void Greeting(void)
			{
				printf("おはよう\n");
			}
		};

		class Gendou
		{
		public:
			// 挨拶
			void Greeting(void)
			{
				printf("問題ない\n");
			}
		};

		void main(void)
		{
			Shinji shinji;
			Rei rei;
			Yui yui;
			Gendou gendou;

			shinji.Greeting();
			rei.Greeting();
			yui.Greeting();
			gendou.Greeting();
		}

		結果:
			お、おはよう
			…………
			おはよう
			問題ない

	上記のクラス、Shinji、Rei、Yui、Gendouは別のクラスですが
	共通してGreeting関数を持っておりインスタンス化して
	関数を実行した結果はそれぞれ別の内容となっています。
	このように各オブジェクト(クラス)で共通した関数を持たせ、
	その関数を呼び出した場合に各オブジェクト毎に違った結果となるのが
	多態性の基本です。

●呼び出しの簡略化
	多態性の性質を利用した処理の代表的なものが呼び出しの簡略化です。
	一つ一つのオブジェクトに対して関数呼び出しを行うのではなく、
	配列等にオブジェクトをまとめて、一気に関数呼び出しを行います。
	この方法を実装した場合、例えばゲームで描画関数Drawを
	オブジェクトの共通関数として実装し、各オブジェクト毎に処理を実装します。
	そして、オブジェクトを管理している側は描画するオブジェクトを
	リストなどでまとめて、それをループ処理呼び出しDraw関数を呼び出すだけで
	プレイヤーや複数の敵、背景、UIなど全てのオブジェクトが描画されます。

	pgtheory_0046
		
	・必要な技術
		呼び出しの簡略化を実装するに辺り必要な技術は
		継承、オーバーライド、仮想関数です。

		以下のリンクで詳細説明しています。
		継承
		仮想関数、オーバーライド

	・例:
		class Ikarike
		{
		public:
			// 挨拶(純粋仮想関数)
			virtual void Greeting(void) = 0;
		};

		class Shinji : public Ikarike
		{
		public:
			// 挨拶(仮想関数)
			virtual void Greeting(void)
			{
				printf("お、おはよう\n");
			}
		};

		class Rei : public Ikarike
		{
		public:
			// 挨拶(仮想関数)
			virtual void Greeting(void)
			{
				printf("…………\n");
			}
		};

		class Yui : public Ikarike
		{
		public:
			// 挨拶(仮想関数)
			virtual void Greeting(void)
			{
				printf("おはよう\n");
			}
		};

		class Gendou : public Ikarike
		{
		public:
			// 挨拶(仮想関数)
			virtual void Greeting(void)
			{
				printf("問題ない\n");
			}
		};

		void main(void)
		{
			Shinji shinji;
			Rei rei;
			Yui yui;
			Gendou gendou;

			// イカリ家
			Ikarike *ikari[4] = {
				&shinji, &rei, &yui, &gendou
			};

			// 挨拶
			for (int i = 0; i < 4; i++)
			{
				ikari[i]->Greeting();
			}

			getchar();
		}

		結果:
			お、おはよう
			…………
			おはよう
			問題ない

	上の例で基底クラスIkarikeの配列に各クラスのインスタンスを入れて
	for文で一気にGreetingを呼び出しています。
	複数のクラスの共通関数を作成し、それを呼び出し側が配列やリストを使用して
	まとめて呼び出すことでshinji.Greeting()やrei.Greeting()などといった
	オブジェクト単体で呼び出す必要がなくなるので呼び出し側の作業が楽になります。

●メリット:
	・汎用性の向上
		各オブジェクトのインスタンス毎に関数を呼び出す必要もなく、
		配列やリストを使用して一気に関数を実行するだけで
		後は各オブジェクトで対応をしてくれるので、
		オブジェクトを使用する側はそのオブジェクトの共通関数の使い方さえ覚えれば
		いくつものオブジェクトを使用することができるようになります。

	・利用者の負担減少
		多態性を使用することで、利用者側の処理が簡易化され
		作業負担が減少します。