• 締切済み

【プログラム】オブジェクト指向ポリモーフィズムとは

一つの同じプログラム(モジュール)をあらゆる場所で呼び出して使いまわすメリットは そのプログラムを何かしら変更する時、何回も何回もいろいろな場所を変更しなくても 一つ変更すればそのプログラムを呼び出している部分 全てに反映されるというところですよね? 逆に、一つの同じプログラムを使いまわすデメリットは、 あらゆる場所で呼び出してる故に、少しでも変更があれば そのプログラムを呼び出している部分すべてに影響を与えてしまい イレギュラーな処理を入れにくいというところですよね? このデメリットをうまくなくしたのが ポリモーフィズムということでいいんですか? 処理を細分化して、プログラムを使いまわすことは使いまわすけども Aの処理 → B-1の処理 → Cの処理 Aの処理 → B-2の処理 → Cの処理 のようにして、差し替え可能な状態にしておき イレギュラーが発生しても ある程度まるごと とっかえなくてもいいようにしておく。 こういうことがポリモーフィズムでということでいいんでしょうか?

  • PHP
  • 回答数1
  • ありがとう数0

みんなの回答

  • mpro-gram
  • ベストアンサー率74% (170/228)
回答No.1

考え方の出発点が違う。「処理」を中心に考えてるうちは、手続き型となにも変わらない。関数ごとにファイル分けするだけでも、プログラムの使い回しもすげ替えもいくらでも出来るが、ポリモーフィズムではない。 オブジェクト指向は、最初に「オブジェクト:情報操作における実体はつまりデータ」ありきで、構築していく。 オブジェクト指向のポリモーフィズムは、スーパークラス(またはインターフェース型)のメソッド呼び出しで、その変数の中身(オブジェクトの実体であるサブクラスのデータ)によって、処理が変わることをいう。 物品管理を例に考えると  スーパークラス「物品情報」 > サブクラスとして、「種類A」「種類B」 上位となる「物品情報」クラスには、物品一般に対して行う処理名としてのabstractメソッド(たとえば「収納」)があり、サブクラスで、その種別ごとに、実際にどう操作するか(どこへ格納するかとか、格納前処理があったりとか)を記述。 「物品情報」型変数に、サブクラス型でインスタンスを代入すると、その「物品情報」型で共通のメソッド「収納」呼び出しが可能であり、実際に呼び出すと、実際に格納されていたインスタンスの型によって、処理の実際が異なっている(異なった場所へ収納)。 呼び出し側では、このインスタンスの実際のサブクラス型を考慮せずに、スーパークラス型として扱うだけでよいので、本体記述側が楽になる。 なので、イレギュラー処理というのとは別物。

関連するQ&A

  • オブジェクト指向の上手い使い方を教えてください

    以下のような、クラスにまとめた処理を一度実行してるファイルがあります。 <?php class Hoge {  public function __construct() {   // 設定値   $this->a = 1;   $this->b = 2;   $this->c = 3;  }  public function main() {   // 設定値を使った処理   print $this->a + $this->b + $this->c;   } } // インスタンス生成・実行 $hoge = new Hoge(); $hoge->main(); ?> 設定値を変更して2回処理を行いたい場合、 一番スマートな形はどれになるか教えてください。 もしくは、それ以外の方法など。 1.設定値を引数で制御し、インスタンスを2回生成する (※設定値自体を引数に渡すことは考えてないです) <?php class Hoge {  public function __construct($flg) {   // 設定値   if ( $flg ) {    $this->a = 1;    $this->b = 2;    $this->c = 3;   } else {    $this->a = 4;    $this->b = 5;    $this->c = 6;   } }  public function main() {   // 設定値を使った処理   print $this->a + $this->b + $this->c;  } } // インスタンス生成・実行 $hoge = new Hoge(true); $hoge->main(); // インスタンス生成・実行 $hoge = new Hoge(false); $hoge->main(); ?> 2.インスタンスの生成・実行は1度のままにし、クラスの処理を変更する <?php class Hoge {  public function __construct() {   // 設定値   $this->a = 1;   $this->b = 2;   $this->c = 3;   $this->a2 = 4;   $this->b2 = 5;   $this->c2 = 6;  }  public function main() {   // 設定値を使った処理   print $this->a + $this->b + $this->c;   // 設定値の変更   $this->a = $this->a2;   $this->b = $this->b2;   $this->c = $this->c2;   // 設定値を使った処理2回目   print $this->a + $this->b + $this->c;   } } // インスタンス生成・実行 $hoge = new Hoge(); $hoge->main(); ?> 3.設定値を変更するメソッドを作り、呼び出す <?php class Hoge {  public function __construct() {   // 設定値   $this->a = 1;   $this->b = 2;   $this->c = 3;  }  public function change() {   // 設定値変更   $this->a = 4;   $this->b = 5;   $this->c = 6;  }  public function main() {   // 設定値を使った処理   print $this->a + $this->b + $this->c;   } } // インスタンス生成・実行 $hoge = new Hoge(); $hoge->main(); $hoge->change(); $hoge->main(); ?> 4.子クラスを作り、2回インスタンス生成・実行を行う <?php class Hoge {  public function __construct() {   // 設定値   $this->a = 1;   $this->b = 2;   $this->c = 3;  }  public function main() {   // 設定値を使った処理   print $this->a + $this->b + $this->c;   } } class Hoge2 extends Hoge{  public function __construct() {   parent::__construct();   // 設定値   $this->a = 4;   $this->b = 5;   $this->c = 6;  } } // インスタンス生成・実行 $hoge = new Hoge(); $hoge->main(); // インスタンス生成・実行 $hoge = new Hoge2(); $hoge->main(); ?> 5.設定値だけ異なるファイルを作りそれぞれ実行する ※省略 よろしくお願いします。m(__)m

    • 締切済み
    • PHP
  • オブジェクト指向でないプログラムってどんなのですか

    オブジェクト指向はそれぞれのインスタンスに属性とオペレーションがあるのがわかりましたが、そうでないプログラムの仕組みなんてありえるんですか? Aを動かす為にBを押したらCがAを動かしてくれたって物を作ろうとしたときにそれぞれをオブジェクトとする以外に方法は無いような気がしますが。 ものを作るときって部品を組み立てたり作用させたりすると思うので、それ以外の組み立て方法ってどうやるのでしょうか?

  • オブジェクト指向によるポケモンの「技」の実装方法

    現在、勉強のためJavaを使ってポケモンのバトルシステムのデモを作成しています。 ポケモンの技を実装したいのですが、ポケモンの技の内容(処理内容)にバリエーションが多すぎて困っています。 多かれ少なかれ、技には似たような性質があるのでポリモーフィズムを使えばよいと思っているのですが、 「次のターン必ず相手がねむる」 「相手の攻撃をすべて自分に向ける」 「敵に同じ技をださせなくする」 など、イレギュラーな要素も多くて実装方法に困っています。 どのようにすればスマートに実装できるか、お力を貸して頂けたら幸いです。

  • C言語 プログラム

    文字列a[]と文字列b[]があり、a[]に含まれるb[]の文字すべてを@に変更する関数mikan[]を教えてください。 また、関数mikan[]を用いて、2つの文字列a[]とb[](空白は含まない)を入力すると関数mikan[]によって変更されたa[]を表示するプログラムを教えてください。よろしくお願いします。 (例 a[] :"a+b+c=abc" b[] :"a=" 上記だったら a[] :"@+b+c@@bc"

  • 再帰的(リカーシブ)プログラムの説明について。

    以下は、再帰的(リカーシブ)プログラムの説明を記載しました。 この説明文でおかしい箇所の添削をお願い出来ないでしょうか? 宜しくお願い致します。 以下からになります。 再帰的(リカーシブ)プログラムとは、プログラムの中から自分自身を呼び出して実行することを再帰的(リカーシブ)アルゴリズムといい、この形式で再帰呼び出しを行うプログラムのこと。 まずは、再帰的アルゴリズムについて、例を使って説明を行いたい。 主プログラムとサブルーチンaがある。 主プログラムは、文字通り、主(メイン)となるプログラム。 サブルーチンは、主プログラムが呼び出して利用する処理をひとまとめにしたもの。 文字通り、サブとなる処理を行う。 主プログラムには、CALL aという命令が記述されている。 これはサブルーチンaを読み出すという命令。 この再帰的プログラムは、処理が終わったら、読み出された場所に帰っていく。 このため、戻り場所を記憶しておかないと帰る事が出来ない。 この戻り場所を記憶するのが、LIFO方式による記憶領域になる。 LIFO方式の記憶領域だから、スタック領域になる。 スタック領域だから、後入れ先出しで戻り場所を記憶していく。 まずは、1回目の呼び出しとして、主プログラムがサブルーチンaを呼び出している。 1回目の戻り場所を記憶しておく。 次にサブルーチンaを見ると、CALL a、つまり自分自身を読み出している。 これが2回目の読み出し。 このように自分自身を呼び出すことを再帰呼び出しという。 同じプログラムの中で自分自身を読み出しているのだが、コンピューターは、あたかも別のサブルーチンがあるように処理が行われている。 この場合、それぞれの処理で、別の変数を用意しながら処理を行う。 このサブルーチンで処理が終わった場合にも、もとに戻る必要がある。 これは2回目の呼び出しになるため、2回目の戻り場所を記憶しておく。 更に、3回目として再びサブルーチンaを呼び出す。 3回目の戻り場所を記憶し、また別の変数を用意しながら処理を行う。 ここで最後のサブルーチンで処理が終わったとする。 処理が終わったら、呼び出された場所に戻る。 戻り場所の記憶を見てみると、上から戻る順番に記録されていることがわかる。 戻り場所はLIFO方式、後入先出しで記録されているから、最後に呼び出した3回目の戻り場所が1番上に記録され、次に2、最後に1が記録されている。 最初は戻り場所を記憶した記憶領域を参照して、3回目に呼び出された場所に戻る。 ここで3の戻り場所が消える。 そして引き続き処理が行われる。 次に、2回目に呼び出した処理が終わり、2回目に呼び出された場所に戻り、2の戻り場所が消える。 また引き続き処理が行われ、1回目に呼び出した処理が終わり、1回目に呼び出された場所(主プログラム)に戻り、1の戻り場所が消える。 そして処理が行われ、プログラム全体が終了する。 このように、プログラムの中で自分自身を呼び出し、戻り場所を記憶しながら実行するようなプログラムを再帰的(リカーシブ)プログラムという。

  • オブジェクト指向の新たな実装方法になるでしょうか?

    トレーディングカードゲームの開発ツール(以降TCGE)というものを作成していたのですが、 オブジェクト指向プログラミングとは考え方が違うと思えるものが出来ました。 考え方を纏めていたところもっと多くの活用が可能かと思い皆様の知恵をお借りしたく思っております。 ※過去にカオス指向(仮)として纏めてみようかと思ったのですが、 他言語等を把握しておらず違いをうまく表現できませんでした。 ●違うと思っている点は以下の通りです。 ・オブジェクトを「物体」と「処理」とに分かれている。 ・「物体」には、「物体」を追加・削除でき、木構造になっている。 ・「物体」には、「処理」を追加・削除でき、「物体」に追加された「処理」は「物体」以降を適用範囲とする。 ・「処理」には、”認識タイプ”が設定され、「物体」に追加された「処理」は”認識タイプ”を持つ「物体」のメソッドとして使用される。 ・「処理」には、優先順位が設定され、「物体」のメソッドを処理する際に、同メソッドの継承関係を構築します。 ●同じ点は以下の通りです。 ・オブジェクトどうしの処理のやり取りを行う。 ・継承関係を持ちません。 ●注意点 ・コーディング例は後ろに載せてあります。 ・TCGEの設定方法をそのままvb風のコーディングにしてあります。 ・まだまだ改善の余地があり、改善案はありますが質問を優先させたいので不備のあるままにしてあります。  例としては、関数を処理オブジェクトとして生成してありますがクラスにしたほうが隠蔽化等が出来て便利など。 ●質問内容としては以下の通りです。 ・言語等で同様の考え方の言語はありますでしょうか? ・「アスペクト指向」等でいう「横断」は実現できるでしょうか? ・コーディング例として必要なものが他にありますでしょうか? ・「物体」の木構造と「処理」の配置を考えるだけでシステムの構築が可能になると考えているのですが需要はあるでしょうか? ●コーディング例 <コーディング例1> function 自己紹介() as string:人(人,1)() '人(人,1)()の説明 '・括弧外の人は、この処理自体を表し、処理生成の1番目で指定します。 '・最初の括弧内の人は”認識タイプ”といわれるもので、処理を適用するかを操作します。この場合、人ならこの処理を行うことになります。 '・最初の括弧内の1は処理の優先順位になります。 '・最後の括弧内は1は処理を生成する際のパラメータになります。  return "人" End Function function 自己紹介() as string:歌える(歌える,1)()  return "歌える" & MyBase.自己紹介() '継承関係がないのにMyBaseがあります。 End Function function 自己紹介() as string:踊れる(踊れる,1)()  return "踊れる" & MyBase.自己紹介() End Function function 自己紹介() as string:アイドル(アイドル,1)()  return "アイドル" End Function Sub main()  ’オブジェクトを生成します  dim 歌って踊れるアイドル=ルート.物体生成(人) 'newでの生成はなく実体オブジェクトに生成追加します  '処理を追加します  dim 人処理=ルート.処理生成(人)  dim アイドル処理=ルート.処理生成(アイドル)  dim 踊れる処理=ルート.処理生成(踊れる)  dim 歌える処理=ルート.処理生成(歌える)  ’アイドルの成長をご覧ください  msgbox(歌って踊れるアイドル.自己紹介()) '「人」と返します。認識タイプは”人”だけです。  歌って踊れるアイドル.認識タイプ追加(アイドル)  msgbox(歌って踊れるアイドル.自己紹介()) '「アイドル」と返します。認識タイプは”人”と”アイドル”です。  歌って踊れるアイドル.認識タイプ追加(歌える)  msgbox(歌って踊れるアイドル.自己紹介()) '「歌えるアイドル」と返します。認識タイプは”人”と”アイドル”と”歌える”です。  歌って踊れるアイドル.認識タイプ追加(踊れる)  msgbox(歌って踊れるアイドル.自己紹介()) '「歌える踊れるアイドル」と返します。認識タイプは”人”と”アイドル”と”歌える”と”踊れる”です。  'おまけでアイドルを辞めさせてみます  歌って踊れるアイドル.認識タイプ削除(アイドル)  msgbox(歌って踊れるアイドル.自己紹介()) '「歌える踊れる人」と返します。認識タイプは”人”と”歌える”と”踊れる”です。 End Sub ・歌って踊れるアイドル.自己紹介()時の処理の流れ 認識タイプに”人”、”アイドル”、”歌える”、”踊れる”がある場合、 処理の順番は追加の逆順(”認識タイプ”の追加順ではありません)なので ”歌える”、”踊れる”、”アイドル”、”人”の順番になります。 <コーディング例2> function 国名() as string:国(国,1)(国名 as string)  return 内容 End Function function 挨拶() as string:挨拶A(人,1)(時間from as string,時間to as string,内容 as string)  if 時間from<= 現在時間 and 現在時間<=時間to then   return 内容  else   return MyBase.挨拶()  endif End Function function 挨拶() as string:挨拶B(人,2)(内容 as string)  '語尾追加  return MyBase.挨拶() & 内容 End Function Sub main()  ’オブジェクトを生成します  dim 日本=ルート.物体生成(国)  dim アメリカ=ルート.物体生成(国)  dim Aさん=日本.物体生成(人)  dim Bさん=日本.物体生成(人)  dim Cさん=日本.物体生成(人)  dim Dさん=アメリカ.物体生成(人)  '処理を追加します  dim 日本処理=日本.処理生成(国,日本)  dim アメリカ処理=アメリカ.処理生成(国名,アメリカ)  dim 挨拶処理1=ルート.処理生成(挨拶A,"0:00","6:00","good evening")  dim 挨拶処理2=ルート.処理生成(挨拶A,"6:00","10:00","good morning")  dim 挨拶処理3=ルート.処理生成(挨拶A,"10:00","19:00","good day")  dim 挨拶処理4=ルート.処理生成(挨拶A,"18:00","24:00","good evening")  dim 挨拶処理5=日本.処理生成(挨拶A,"0:00","6:00","こんばんわ")  dim 挨拶処理6=日本.処理生成(挨拶A,"6:00","10:00","おはよう")  dim 挨拶処理7=日本.処理生成(挨拶A,"10:00","19:00","こんにちわ")  dim 挨拶処理8=日本.処理生成(挨拶A,"18:00","24:00","こんばんわ")  dim 挨拶処理9=Bさん.処理生成(挨拶B,"ニャン")  msgbox(Aさん.挨拶()) '0~6時は「こんばんわ」、6~10時は「おはよう」、10~18時は「こんにちわ」、18~24時は「こんばんわ」  msgbox(Bさん.挨拶()) '0~6時は「こんばんわニャン」、6~10時は「おはようニャン」、10~18時は「こんにちわニャン」、18~24時は「こんばんわニャン」  msgbox(Cさん.挨拶()) '0~6時は「good evening」、6~10時は「good morning」、10~18時は「good day」、18~24時は「good evening」 End Sub ・オブジェクトと処理の木構造 ルート(挨拶処理1~4)   日本(挨拶処理5~8)     Aさん     Bさん(挨拶処理9)   アメリカ     Cさん ・Aさん.挨拶()時の処理の流れ 処理対象のメソッドは、木構造から挨拶処理1~挨拶処理8になります。 (日本処理は”認識タイプ”が異なるので対象になりません) 挨拶処理1~挨拶処理8の処理の優先順位で並べ替えると 挨拶処理8、挨拶処理7、・・・、挨拶処理1 の順番になります。 並び替えた順番で所謂「継承」を構成して処理しますので、 挨拶処理8を処理し、18:00~24:00の間なら"こんばんわ"を返し、 そうでない場合、挨拶処理7を処理し、10:00~19:00の間なら"こんにちわ"を・・・と処理されます。 以上よろしくお願いします。

  • 関数を使ったプログラムについてなのですが・・・

    ・変数a,bの内容を入れ換える処理を関数を用いて実行するためのプログラム と ・変数a,bを与えたときa+bとa-bを計算する処理を関数を用いて行い、和と差を表示させるためのプログラム はどう作ればいいか分かりません…。 教えてください。

  • ExcelVBAのプログラムをJavaへ変換

    if(a <>"A" And b<> "A" ) Then 処理 End if というプログラムがありました。 <>の部分がよくわからないです。 これをJavaに変換するとすれば、どの様なプログラムになるのでしょうか? 教えていただけるとありがたいです。

  • プログラムが動きません

    一昨日教えていただいた入力された文字を13ずつずらして表示する暗号化プログラム(文字列は一行最大80文字、10行分の入力を受け付けたら終了)、がまだ動きません(下記のプログラム)。エラーにはならないのですが、何も表示されませんが10回入力すると終了はするが、何も表示がされません。どういうプログラムならよいのかもう一度どなたかお教え下さらないでしょうか? #include <stdio.h> #include <stdlib.h> #include <ctype.h> char e[81]; int anngou (int c, char b[81]) { if(b[c] >= 'a' && b[c] <= 'z') { if(b[c] >= 'a' && b[c] <= 'm') { e[c] = b[c] + 13; } else { e[c] = b[c] - 13; } } else { if(b[c] >= 'A' && b[c] <= 'Z') { if(b[c] >= 'A' && b[c] <= 'M') { e[c] = b[c] + 13; }else{ e[c] = b[c] - 13; } } } return e[c]; } int main(void) { int a, c, d; char b[81]; a = c = 0; while (a <= 9) { printf("Input some words: "); fgets(b, 81, stdin); for (c = 0; c <= 81; c++) { if (b[c] == '\0') { d = c; break; } } c = 0; while (c >= d) { anngou(c,b); printf("%c", e[c]); c++; } printf("\n"); a++; } exit(0); }

  • このようなプログラムを探しています。

    例えば「A」「B」「C」の三つのサイトがあり 「A」にアクセスしたら「B」に自動で飛び、そして「C」にも飛ぶような仕組みを作りたいと思っています。 「B」にプログラムを置けば簡単だと思ったのですが、そうしてしまうといろいろと都合が悪くなってしまうので、「A」のページのプログラムだけでこのようなことを出来ないかと考えました。 はたしてこのようなことは可能でしょうか? PC&携帯サイトで実現できるものを探しています。 読みづらい文で申し訳ありません。どなたかよろしくおねがいします。