• ベストアンサー

オブジェクト指向プログラミングの多態性のメリット、目的は?

オブジェクト指向プログラミングを学んでいます。 基本概念の多態性がどうも理解できません。 メリット、目的はなんなのでしょうか? 上位クラスを継承し、 その継承されたクラスのメソッドを上書きするということと何が違うのでしょうか? 学習の参考にしている書籍の中には ”多態性を使ったオブジェクト指向プログラミングの典型例”として、 異種リスト(=上位型に下位型を代入し、一族のオブジェクトを一括管理する)を紹介しています。 多態性はこのような使用のみを目的としているのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • otu_otu
  • ベストアンサー率31% (17/54)
回答No.3

 異種リストを多態性を用いて実現するのは、一つの例ですね。#2の方の方針も基本的には同じ応用例だと思います。  じつは、多態性には、もっと重要な応用例があります。そして、これは現在のWindowsMFCプログラミングで多用されています。  Windowsはイベントドリブン型の実行方式であることは、ご存知でしょうか?ここに大きなポイントがあるのです。  いまクラス(CView)があるとしましょう。 class CView{ public:   virtual void OnDraw(CDC* pDC); };  いま、このCViewクラスには仮想関数OnDrawがあったとします。これは、描画が必要になったときに、Windowsプロシージャから呼び出される関数です。 さらにここで、CViewからクラスCMyViewを派生させましょう。 class CMyView : public CView{ public:   virtual void OnDraw(CDC* pDC); };  ここで、OnDrawの実体部に具体的な描画操作を書いておくとします。  さて、いままでの話は準備でした。 ここからが本題です。 いま、アプリケーションのビューを登録するのに、 void Add(CView* pView); となる関数が与えられているとしましょう。 この関数によってCViewが登録されると、描画が必要な際に、   pView->OnDraw(pDC); を自動で呼び出すようになっています。 もしここで、   Add(new CMyView()); と登録すれば、描画が必要な際には自動的に、 CMyView::OnDraw(CDC* pDC)を呼び出してくれるわけです。  これは通常の関数によるオーバーライドでは実現できません。オーバーライドしていたのでは、CView::OnDraw(CDC* pDC);が呼び出されてしまいます。  もしかしたら、Add(CView* pView)について疑問が残るかもしれません。  Add(CMyView* pMyView);という関数を作って、pMyView->OnDrawを呼び出せば、確かに同じ動作をしてくれるでしょう。  しかし、Add(CView* pView);はライブラリで規定されている関数なのです。つまり、C言語でのprintfのようなもの。Add(CMyView* pMyView);という関数をつくるということは、ライブラリを有効利用しないということなのです。  そのような観点から言えば、先ほどの異種リストも同じことが言えます。抽象度が高い「動作」の部分をライブラリにしておきさえすれば、具体的なものを考えたときに、すばやく目的の動作を実現できる。  この概念はWindowsプログラミングのようにプログラム規模がとても大きくなる場合は、どうしても利用しなくてはならないでしょう。  確かに多態性はわかりにくい概念ではあります。 しかし、抽象度の高いプログラムがあらかじめ作成されていて、それを具体的な目的で利用するといった場合、有効な方法なのです。

sambarunba
質問者

補足

回答、ありがとうございます! 説明していただいて、 さらに納得の度合いが増しました^^ これから、実際にどんどん実装してみて理解度を増してゆきたいと思います。 ひとつ確認させていただきたいのですが、 >もしここで、 >  Add(new CMyView()); >と登録すれば、描画が必要な際には自動的に、 >CMyView::OnDraw(CDC* pDC)を呼び出してくれるわけです。 > これは通常の関数によるオーバーライドでは実現できません。 >オーバーライドしていたのでは、CView::OnDraw(CDC* pDC);が呼び出されてしまいます。 は、書籍の中に説明にあったのですが、 通常の関数のオーバーライドでは上位型への回帰となる (つまり、仮想関数のオーバーライドでないと、上位型メソッドのふるまいとなる)、 という理由からでしょうか?

その他の回答 (3)

  • root139
  • ベストアンサー率60% (488/809)
回答No.4

サブルーチンと対比すると分かりやすいと思います。 サブルーチンを利用すると呼び出されるプログラムを共通化できますが、多態性を利用すると呼び出し元のプログラムを共通化できます。 strategy パターンなどは、典型的な例だと思います。 http://www.atmarkit.co.jp/fdotnet/designptn/designptn03/designptn03_01.html 上記の様な説明は「オブジェクト指向でなぜつくるのか」という本に載っていました。 http://bpstore.nikkeibp.co.jp/item/main/148222819570.html

sambarunba
質問者

補足

回答ありがとうございます! >サブルーチンを利用すると呼び出されるプログラムを共通化できますが、 >多態性を利用すると呼び出し元のプログラムを共通化できます。 の部分を見て、 そういえば…!と、ふとどこかでその図を目にしたのを思い出しました。 今になって納得できた感じです。 #2さんのおっしゃっていたことをさらに理解できました。 >strategy パターンなどは、典型的な例だと思います。 >http://www.atmarkit.co.jp/fdotnet/designptn/designptn03/designptn03_01.html ざっと見ていました。 まだ、よく分らないようです^^; 実際にコードを打ち込んでみたほうがいいみたいですね。 試してみたいと思います。

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.2

多態性は非常によく使います。 そうとは意識しないで使っている場合も結構あると思います。 例えば、「処理の大部分は共通なのに一部分だけ違う」場合、 実現するのには次の3つが考えられます。 A.全て違うメソッドにする。 B.メソッドの中で、タイプ別に分岐処理する。 C.処理の内容が違う部分をオブジェクトにして多態性を使う。 Cの方法を使うとコードを共通化でき、さらにすっきりとさせることができます。 具体的には、ソートなんていうのがあります。 ソートというのは、 1.レコードを取り出す 2.レコードを比較する。 3.その結果によってレコードを入れ替える。 というのが概略です。 このうち、2だけは様々な方法が存在します。 (レコードのどこを比較するか、大小をどう比較するか等) そこで、比較のロジックだけをオブジェクトにしてソートルーチンに渡します。 ソート(レコード群 records, 比較オブジェクト comp){  recordsからレコード1を取り出す  recordsからレコード2を取り出す  int r = comp.compare(レコード1,レコード2)  rが正の数なら入れ替え } 昇順でソートしたければ、そのような結果を返すように「比較オブジェクト」のcompareメソッドを 上書きしたクラスを定義しておくわけです。 このように、多態性はいろんなところで使われています。

sambarunba
質問者

補足

回答、ありがとうございます。 なるほど便利ですね! おっしゃっていることが理解できたら、 なんか感動してしまいました^^

  • coQ
  • ベストアンサー率28% (15/52)
回答No.1

デザインパターンについて学ばれると多能性の意味が理解できるかと思います。

sambarunba
質問者

補足

回答、ありがとうございます。 学習を進めてゆき、 オブジェクト指向の基本的なことが理解出来次第、 デザインパターンも学んでみたいと思います。

関連するQ&A

  • オブジェクト指向について

    趣味でプログラミングをしているのですが オブジェクト指向の概念がうまく理解できていないので 教えていただけませんでしょうか? 解説本などを読むと、オブジェクト指向のクラスを動物クラスを継承して犬クラスや猫クラスなどと解説してあるのですが。 どうも、僕がプログラム設計するとしっぽクラスや泣き声クラスなどといった違った動物の類似機能をまとめてのクラスをつくり各メソッドとしてしまいまっています。 動物クラスや乗り物クラスを組み合わせてプログラムを設計する事ができません。 本格的なプログラムを組む用途では無いので気にしなくても目的の機能が実装できれば問題無いと知人からは言われ(面倒なので教えたくないのかもしれませんが)そのまま来てしまいました。 最近、気になって来たので。 正しい使い方を身に着けたいと思いチャレンジしていますが、変な癖がついていて犬や猫クラスなどと思いながら設計していると思考が止まってしまいます。 そこで、下記のことを教えていただけませんでしょうか? (1)泣き声クラスなどの同機能を1つのクラスにしてしまう設計しか出来ない(発想できない)のは考え方のどこがわるいのでしょうか? (追記:一部分だけならペンギンクラス猫クラスなどと言う動物クラスの継承的な発想はできるのですが実際のプログラミングの際は動物のようなわかり易い物オブジェクトとして目に見える物体ではない事柄をオブジェクト化にする事が難しく感じるのではないかと思います。) (2)今までの小さい規模での開発なら、クラスのつくり方がおかしくても不具合は無かったのですが、どのような時に困る事があるのでしょうか?(解説などでも再利用性などと、さらっと解説されていますがイマイチぴんときません) (3)正しくオブジェクト指向がマスター出来ている方にとって、どのクラスにどのメソッド実装するか悩む事などはあるのでしょうか? また、設計で一番悩むのはどのあたりですか? (4)UMLのマスターは必須でしょうか?(現在は、なんとなくUMLぽい感じでメモ書きをつくり、えせオブジェクト指向でプログラムを組んでいます。) (5)その他アドバイスがあればお願いします。 ※乱文で問題もハッキリせず質問の整理等がうまくいっていないと思いますが1つの項目だけでも構いませんので、ご教授お願いします。

    • ベストアンサー
    • Java
  • 【オブジェクト指向について】

    【オブジェクト指向について】 こんにちは。初めて質問をさせていただきます。 さて、ただいまVBを勉強中なのですが、オブジェクト指向のところで躓いてしまいました。 質問したい事は以下の点です。 (1) オブジェクト指向の理解について   オブジェクト指向とは、プログラミングをするときに変数や機能などをクラスというものに格納しておくことで、プログラミングを円滑にすすめるための概念であると理解していますが、この理解は正しいのでしょうか? ご回答お待ちしております。よろしくお願いいたします。

  • オブジェクト指向プログラミングについて

    VisualBasicを対象にしたオブジェクト指向プログラミングに関する参考書、Webサイトなどはないでしょうか。 現在、クラスモジュールなどを多用しオブジェクト指向プログラミングを実践しているつもりですが、あまり勉強したわけではないのでいまいちよくわからないです。 (オブジェクト指向プログラミングのメリットとデメリットなど)

  • オブジェクト指向に関して。

    Javaの解説本を読んでオブジェクト指向プログラミングという物があることをしりました。その本には「オブジェクトはデータとそのデータを扱うための機能を持っている。この機能はメソッドと呼ぶ。クラスは設計図のような物で変数とメソッドから構成されている。設計図を実際に形にした物がインスタンスである。」と書いてありました。私はオブジェクト=クラスのような感じがしたのですが、実際のところオブジェクト=クラスでいいのでしょうか?  また、友人に話したところ、オブジェクト指向はサブルーチンに似ているといっていました。私はプログラミングの知識が全くないのでサブルーチンという物が何なのかわからないのですが、サブルーチンとオブジェクト指向の考え方は違うような気がするのです。友人に説明して納得させるにはどうしたら良いのでしょうか? ぜひ、力を課してください。

  • オーバーロードはオブジェクト指向プログラミングの枠組みで語られるべきか

    一部の書籍やサイトでは、オーバーロードがオブジェクト指向プログラミングの特徴であるかのような記述が見受けられるのですが、私はそれに疑問を感じます。 オーバーライドはクラス・継承に関わるためOOP特有のものであると思うのですが、オーバーロードはクラスとは全く切り離して考えられるからです。 確かにオーバーロードはクラスを作るときに有用な技術ではありますが、例えばC言語のような非オブジェクト指向言語でオーバーロードが使えたとしても、それなりに機能するはずです。 ひょっとしたら 「オーバーロードもオーバーライドもポリモーフィズムだろう」 ↓ 「ポリモーフィズムといえばオブジェクト指向」 のような話の展開でしょうか(いや、さすがに無理があるか…)。 皆様はどうお考えでしょうか。 ご意見お聞かせ下さい。

  • オブジェクト指向とは

    オブジェクト指向の本をたくさん読んでみましたが 全部書いてあることが難しくていまいちピンときません。 要は簡単にいうと、クラスを作ってその中にメソッドを 作ってロジックの中でその中のクラスを使い分けていく という考え方がオブジェクト指向というのでしょうか? 簡単でいいのでわかりやすくオブジェクト指向というのを教えていただけないでしょうか?友人に聞くとオブジェクト指向を説明すると2時間はかかると言われてしまいました。

    • ベストアンサー
    • Java
  • オブジェクト指向プログラミング

    一般に、オブジェクト指向プログラミングといわれているプログラミングに関してですが、 「関数・手続きを使用するプログラミング」と 「クラスを作成してプログラミング」というのは おおきな違いがあるのでしょうか? (クラスを作成しなくても関数・手続きで、プログラミングすれば 一緒じゃないかなぁと思っていますので・・・。) どなたか、これに関して、お返事をして頂けたら今後いろいろな面でかなり助かります。

  • オブジェクト指向の教え方

    新入社員にJavaを教えているところなのですが、オブジェクト指向プログラミングをどのように教えていいか困っています。 全員がC言語研修を受講済みで、さらにJava言語も、継承やオーバーロード、例外まで一通り教えて、一応理解しています。 そこで、次のレベルとして、C言語風のプログラミング(「プログラム=関数の集まり」の考え方)から、オブジェクト指向(「プログラム=オブジェクトの集まり」の考え方)に意識改革させたいところです。 問題領域をオブジェクトの集まりとしてとらえ、そこからクラスを抽出していく、という説明がよくありますが、 「何をオブジェクトにするのか」「どのようにクラスを抽出したらいいのか」の部分を詳しく教えたいのですが、どのように説明したらいいでしょうか。また、参考になるWebサイトなどありませんでしょうか? 自分が普段作るときは、ほぼ「勘」でクラス設計していますので、それでは教えられなくて困っています。よろしくお願いします。

    • ベストアンサー
    • Java
  • 本当にオブジェクト指向プログラミングっていいのでしょうか?

    いつもお世話になっております。 VC++初心者です。 現在、VC++6.0、MFCのソース修正で四苦八苦しています。 (コーディングするよりも。ソースを追うので苦労してます。) (初心者の私が言うのも難ですが、オブジェクト指向云々言う前に  ソースのif文節が異常に長かったり、3重以上ループが出てくると  とても嫌になります、、、) 一般的(?)に、プログラミングは 手続き型プログラミングよりオブジェクト指向プログラミングが 開発効率がよい、と重宝されているようですが、 どうも納得できていません。 (その手の書籍を2,3冊読みましたが消化不良に終わっています。) 個人的には、手続き型プログラミングの方が好きです。 というのも、慣れているからかもしれませんが、 ソースが追いやすいし、見やすいと思います。 逆にオブジェクト指向プログラミングでは、 ・継承されすぎると、基本クラスまで追うのが一苦労。 ・インスタンスをつくってから、関数を呼ぶのが面倒な気がする。  (手続き型なら関数呼び出しのみで済みます。) ・インスタンスをdeleteし忘れて、メモリを圧迫する危険がある。  (ガーベージコレクションというものもあるようですが、  どこで何を消しているか不安です。) ・ソースを追いにくい(慣れの問題なのでしょうか、、、) そこでですが、 「手続き型は~~で大変だけど、オブジェクト指向ならこんなにすばらしい」 というような対比的に具体例を挙げて説明されている 書籍、サイトの紹介、または、よい助言を頂けませんでしょうか。 また、上記に伴い、 ・手続き型で組んで失敗した例(オブジェクト指向型にすれば良かった例) ・オブジェクト指向型で組んで失敗した例(手続き型にすれば良かった例) も宜しければ教えて頂きたく、お願いします。 (成功例のみよりも、失敗からの成功例を教えて頂けると嬉しいです。) 長くなりましたが、宜しければご教授下さい。

  • オブジェクト指向について

    オブジェクト指向における  オブジェクト、インターフェース、実装、クラス という概念を教えてください>< 実例があると助かります。。