10分SHAREツイートシェアはてブLINEPocket今井こんにちは!今井(@ima_maru)です。ポリモーフィズムってなに?どんなメリットがあるの?仮想関数とは?このような疑問をプログラミングが初めての方にもわかるように、わかりやすく解説します。オブジェクト指向の3つの特徴の1つのポリモーフィズムというのはどういうものなのでしょうか。最後にポリモーフィズム(polymorphism)ポリモーフィズムとは、オブジェクトなどのデータ型に関する操作が統一的であることである。優しく言えば、異なるオブジェクト間の操作を一緒に処理できるというオブジェクト指向の特徴の一部。これでもまだ難しいように言っている気がします。言ってしまえば、異なるオブジェクトの操作をまとめてできるよって機能です。これから詳しく解説していきます。異なるオブジェクトの操作をまとめてできる[/box02]これはこれから紹介するサンプルコードの一部です。最終的にこんなコードを仕上げていくのが今回の記事の目標です。{human[i]->Hello();}次の項目で名前の由来を書いていますが興味のない方は飛ばしてください。多相性と訳すことができます。読み方は、ポリモーフィズムのほかに、ポリモルフィズムとも読めるそうです。[r]の発音の問題ですね。poly(ポリ)には「多くの」という意味があります。poly-ethylene(ポリエチレン)がいい例で、エチレンが複数個集まってできている有名な化学物質です。ポリ袋、シャンプーやリンスの容器もポリエチレンで作られているらしいですよ。morphism(モーフィズム)は、簡単に「変化」といえばいいのかなと思います。あるものからあるものへの「変化」を表しています。数学的に言えば、射と言われたりします。あるものからあるものへの写像なんて言ったりしますね。関係ない話なのでわからなくても大丈夫です、「変化」と思ってもらって構わないです。以上より、ポリモーフィズム(polymorphism)とは、「多くの」「変化」と直訳することができますね。「多くの変化が可能になる」という意味で「多様性」という言葉が当てはまるのだと思います。多様性ざっくりしたイメージここでは導入として漠然としたイメージを書きます。このようなJap_langの構文があったとしましょう。田中君の髪形はリーゼントだ。木村君の髪形はマッシュだ。このようになったとします。大事な要素は3つです。「呼び出し元」の「関数」は「結果」という構文になっています。○○が変われば髪型という関数が結果□□を返します。この際、髪型という関数名はいつも同じです。「同じ関数なのに呼び出した人によって結果が変わってくる。」というのがポリモーフィズムの考え方です。これをC++に実装することが目標です。イメージはこんな感じ。{クラスメイト[i]の髪型();}}実際にはもう少し付け加える部分があります。下のほうで解説していきます。私は、ポリモーフィズムをこう考えるとよいと思っています。同じ名前の関数がオブジェクトによって違う働きをすること例えばアメリカ人のクラスと日本人のクラスを作ってそれぞれに同じ名前Hello()という挨拶を表示する関数を作ったとします。}};アメリカ人のクラスの挨拶の関数Hello()は”Hello”と表示されるプログラムです。日本人のクラスの挨拶の関数Hello()は”こんにちは”と表示されるプログラムです。実際にオブジェクトを作ってHello()関数を起動してみましょう。japanese;//それぞれでHello()関数を呼び出すamerican.Hello();japanese.Hello();}これは当たり前ですが、Helloこんにちはこう表示されます。○○.Hello()→□□このように○○の部分を変えて□□が表示出来たら便利ですよね。これがポリモーフィズムです。同じHelloという名前の関数が呼び出し元によって違う働きをすること。多くの国の方のクラスを作ってみましょう。}};これを全員分表示するにはこうします。german;//それぞれでHello()関数を呼び出すamerican.Hello();japanese.Hello();indian.Hello();korean.Hello();chinese.Hello();russian.Hello();german.Hello();}これは大変ですよね。ちなみに実行結果はこう出ます。タークここであることに気づくわけです。メンバ関数「Hello()」って名前同じだ。実行する人の名前だけ変えればいいのでは?そうですよね、○○.Hello();となっているわけですし、○○だけ変えて実行できないかなあと考えると思います。後ほど説明しますが、結果的にはこう書けばいいことになります。{human[i]->Hello();}}このようにmain文がきれいにまとまったのがわかると思います。for文で一気に回せています。オブジェクト型のポインタを格納する配列、for文などですね。下で解説していきます。変更点の一番大きな点はこちらです。{human[i]->Hello();}このように「それっぽく」なったこと。これがまさにポリモーフィズムの結晶です。上でも書いた通り、ポリモーフィズムとはある一つの機能ではありません。日本語で言えば「多様性」、言い換えれば、異なるオブジェクト間の操作を一緒に処理できるというオブジェクト指向の特徴の一部です。継承などと違って、ポリモーフィズムはこうやって使うんだとかってのが書きにくい部分でもあります。ここでは、オブジェクト指向の特徴である、ポリモーフィズムを実現するために必要な機能や知識を紹介していきます。基底クラス-派生クラス、言い換えれば親クラス-子クラスといえます。この関係がわかる方は飛ばしていただいて大丈夫です。継承がわからない方はこちらをご覧ください。【C++】継承とは?わかりやすく解説!基底クラスへのポインタこれをわかっていないと今回のポリモーフィズムの例は理解できないはずです。基底クラスへのポインタは派生クラスのポインタも代入することができるというところさえわかっていれば大丈夫です。こちらの記事で解説しています。ついてはC++のポリモーフィズムの一番大切な部分です。「ほぼ"100%流れが来る職業"に、ほぼ"100%転職できる"としたら、あなたは悩みますか?それとも今すぐ行動しますか?」なおその先にある答えは行動した人しか知れないよ!\ホリエモンも認めた/転職成功率97%のプログラミングスクールはこちらポリモーフィズムのメリットポリモーフィズムを使う(使うといっていいのかわからないですが)メリットというのはズバリ、変更に強くなるという点が大きい思います。{human[i]->Hello();}ポリモーフィズムのない場合はこれ↓です。//それぞれでHello()関数を呼び出すamerican.Hello();japanese.Hello();indian.Hello();korean.Hello();chinese.Hello();russian.Hello();german.Hello();かっこ悪いし、こんな長々と書きたくないです。このような処理がしたいとき、またこのコードを書かないといけなくなります。{human[i]->Hello();}こう書くのと、//ポリモーフィズムなし//それぞれでHello()関数を呼び出すamerican.Hello();japanese.Hello();indian.Hello();korean.Hello();chinese.Hello();russian.Hello();german.Hello();どっちがいいですかって話。派生クラスが増えたら増えただけ、ポリモーフィズムのない下のコードのほうが厄介ですよ。次にすべてのクラスに新たなメンバ関数Hoge()が増えたとします。}};ちなみに0を返すだけの意味ない関数です。ほかの子クラスにも作り、親クラスには純粋仮想関数を作っておきます。この関数を一緒に呼び出してみましょう。//ポリモーフィズムなし//それぞれでHello()関数を呼び出すamerican.Hello();japanese.Hello();indian.Hello();korean.Hello();chinese.Hello();russian.Hello();german.Hello();//それぞれでHoge()関数を呼び出すamerican.Hoge();japanese.Hoge();indian.Hoge();korean.Hoge();chinese.Hoge();russian.Hoge();german.Hoge();非常に格好悪い。ポリモーフィズムを使えばこんな書き方ができます。{human[i]->Hello();human[i]->Hoge();}なんて美しいのでしょうか!このように記述量が減るというのも変更に強い点ですが、さらには、変更点や追加点がわかりやすいという点も変更に強い点です。7」というのは「これから大文字のNは7という意味で定義しますよ」という構文です。{human[i]->Hello();}}例えば、新しいクラスFrenchが増えたとします。インスタンスを作り最後にポインタの配列に追加するだけです。ポリモーフィズムのないときは、様々な場所で変更、追加する必要が出てくるはずです。(今回のサンプルコードだけだと少ないですが。)最後に理解や解釈が難しいポリモーフィズムですが、私も最初理解に苦しみましたので、いろんな記事を見るとか、直接触れてみて感じてみるとかするととてもいいと思います。メリットなどは個人的な見解も含んでいますので、実際にプログラミングしてみてここは違うんじゃないと思うこともあるかもしれません。一つ参考程度に見てください。この記事はプログラミングを始める方用に作っていますので、これからプログラミングを始める方に少しでも役に立てれば、参考にしてもらえればと思います。オブジェクト指向のメリットとは?例に例えてわかりやすく解説!最後まで読んでいただきありがとうございます。コメントをキャンセルメールアドレスが公開されることはありません。週1でブログ書いてます。