オブジェクト指向の「ポリモーフィズム」とは?超わかりやすく解説します!
こんにちは!
現役Webエンジニアの今井(@ima_maru)です。
この記事をご覧になっている方は「オブジェクト指向」というキーワードを聞いたことがあるのではないでしょうか。
これは、いままでのプログラミング手法と異なり、「モノが自主的に作用しあう形でプログラムを組むというようなプログラミング手法」などと言われます。
「こんな難しく言われてもわかんねえよ!」「何言ってんだよ!」って方。私もそうでしたのでご安心ください。
私はこの概念を理解するのに、1か月くらいかかりました。そのくらい理解が難しいものであるということは確かです。
大まかに言って、オブジェクト指向を構成する要素は「継承」「カプセル化」「ポリモーフィズム」の3つがあります。これら3つはオブジェクト指向の基盤を担っているものです。オブジェクト指向を理解するならば避けては通れない道でしょう。
カプセル化については以下の記事で詳しく解説しているので、是非併せてご覧ください。
今回は、その中でも一番理解が難しいとされる「ポリモーフィズム」について以下のようなことを解説します。
- ポリモーフィズムとはなに?
- どんなことができるようになるの?
- ポリモーフィズムのメリットは?
全く知らない人は、本当に理解するのに時間がかかるかもしれません。
なので皆さんにより効率的に理解してほしいという想いから初めてプログラミングを学ぶ方にも優しい言葉で、できるだけわかりやすく解説していこうと思います。
オブジェクト指向の3つの特徴の1つのポリモーフィズムというのはどういうものなのでしょうか。
見ていきましょう!
オブジェクト指向のポリモーフィズム(polymorphism)とは?
ポリモーフィズムとは、オブジェクトなどのデータ型に関する操作が統一的であることである。
なんて言われますが、正直こんな難しいこと言われてわかる人は少ないと思います。
もっともっと優しい言葉で解説しようと思います。
ポリモーフィズムという名前の由来・意味
ポリモーフィズムとは、日本語で「多様性」「多態性」「多相性」と訳すことができます。
読み方は、ポリモーフィズムのほかに、ポリモルフィズムとも読めるそうです。[r]の発音の問題ですね。
単語の構造的には poly と morphism 分けられます。
poly(ポリ)には「多くの」という意味があります。
morphism(モーフィズム)は、簡単に「変化」といえばいいのかなと思います。
あるものからあるものへの「変化」を表しています。
以上より、ポリモーフィズム(polymorphism)とは、「多くの」「変化」と直訳することができますね。
「多くの変化が可能になる」という意味で「多様性」という言葉が当てはまるのだと思います。
poly(多くの)morphism(変化)→ 『多様性』
ポリモーフィズムとは、実は当たり前のこと?
実は、ポリモーフィズムとは、私たちの生活の中に「当たり前」に成り立っていることなのです。
まずは、難しく考えずにこう考えてください。
「モノ」が「そのモノ」らしく振舞うこと
まずは、簡単な例を出します。
このように犬と猫とアヒルがいます。
この3匹はそれぞれ、どのように鳴くでしょうか?
これは簡単ですよね。
そして、とても当たり前のように感じると思います。
それでは、ここからプログラミングの話に寄せていきます。
まずは、犬と猫とアヒルのクラスを作り、それぞれに鳴くという関数を作成します。
クラス 犬 { 鳴く() { "ワン" } };
クラス 猫 { 鳴く() { "ニャー" } };
クラス アヒル { 鳴く() { "クワッ" } };
それぞれの鳴き声を、こんな感じで表してみました。
そして、先ほどの「?は??のように鳴く」という風に表せば、
犬.鳴く();
猫.鳴く();
アヒル.鳴く();
このように書けるでしょう。
そして以下のように関数が実行されるはずです。
- 犬.鳴く() → "ワン"
- 猫.鳴く() → "ニャー"
- アヒル.鳴く() → "クワッ"
ここで考えるわけです。
このように考えれば、以下のような処理ができるはずです。
動物 = { 犬,猫,アヒル };
for (動物) { 動物.鳴く(); }
こんな感じでしょうか?
動物に犬、猫、アヒルが順に入って、鳴き声という関数を呼び出します。
こう書けば、犬は「ワン」、猫は「ニャー」、アヒルは「クワッ」と鳴くはずですね。
結果として先ほどの3行のコードと同じ処理を、きれいにまとめることができました。
ここで考えてもらいたいのが、どの動物に対しても鳴くという処理が同じ動作しかできないのであれば、この構文が使えないということです。
動物 = { 犬,猫,アヒル };
for (動物) { 動物.鳴く(); }
例えば、犬を入れても猫を入れてもアヒルを入れても、すべてにおいて「クワッ」と鳴いたらおかしいですよね?
逆に言えば、「中に入るものによって同じ関数でも違う処理を行える」というプログラミング言語自体の特徴があるからこそ、このような構文が使えるようになるということです。
先ほどの図を使えば、
最初の?によって鳴き声が変わるという特徴があるからこそ成立するのです。
そして、この特徴こそが「ポリモーフィズム」と呼ばれます。
もう一度言います。
「中に入るものによって同じ関数でも違う処理を行える」というプログラミング言語自体の特徴
これこそが「ポリモーフィズム」なのです。
オブジェクト指向プログラミング言語では、この特徴を当たり前のように持っています。
というより、「モノ」を基準として考える=オブジェクト指向言語では、ポリモーフィズムがなくては話にならないのです。
もうここまでくれば、なんとなく理解できるはずです。
はじめに書いた、
「モノ」が「そのモノ」らしく振舞うこと
ということを、オブジェクト指向プログラミングに寄せた表現にすれば、
呼び出した関数が呼び出し元のオブジェクトに適した振る舞いをすること
と言い換えることができます。
この、オブジェクト指向言語が当たり前に持つ特徴、仕組みこそが「難しい」といわれるポリモーフィズムの根本の意味なのです。
わざと難しい表現にすれば、「オブジェクトなどのデータ型に関する操作が統一的である」というような言い方になるわけです。
ポリモーフィズムのメリット
ざっくりと概要をお話ししたところで、「ポリモーフィズムを用いるとどのようなメリットがあるのか?」というところについて解説していきます。
ポリモーフィズムのないプログラミングに比べて以下の点で優れているといえます。
- コードがきれいにまとまる
- プログラムの変更に強くなる(柔軟性が高くなる)
2つのメリットは根幹をみれば、どちらも似たりよったりな部分です。
それぞれ、ポリモーフィズムを利用しない場合と比較して、解説していきます。
コードがきれいにまとまる
ポリモーフィズムを利用すれば、とてもコードがきれいにまとまります。
これは実際にコードを見てもらったほうがわかりやすいので、プログラミング言語「C++」を使ってを紹介します。
- 人間クラスを継承した7か国の人のクラスがある
- そのクラスにはあいさつを表現した関数「Hello()」がある
- それぞれの7つの国のあいさつを呼び出す処理を書く
それではまずは、ポリモーフィズム利用しない場合。
// それぞれでHello()関数を呼び出す
american.Hello();
japanese.Hello();
indian.Hello();
korean.Hello();
chinese.Hello();
russian.Hello();
german.Hello();
「ちょっとカッコ悪い!」
つぎに、ポリモーフィズム利用した場合。
// それぞれのオブジェクトのポインタを格納する配列を用意
Human* human[N] =
{ &american,&japanese,&indian,&korean,&chinese,&russian,&german };
// それぞれでHello()関数を呼び出す
for (int i = 0; i < N; i++) {
human[i]->Hello();
}
きれいにまとまった感じが見て取れるでしょうか。(ポインタとかはわからなくて大丈夫です。)
こんな風に、ポリモーフィズムを利用すれば、きれいにまとめることができるのです。
またこれは、変更に強くなる柔軟性も兼ね備えているのです。
変更に強くなる柔軟性
先ほどのコードを再利用します。
// それぞれのオブジェクトのポインタを格納する配列を用意
Human* human[N] =
{ &american,&japanese,&indian,&korean,&chinese,&russian,&german };
// それぞれでHello()関数を呼び出す
for (int i = 0; i < N; i++) {
human[i]->Hello();
}
ポリモーフィズムを利用しない場合はこれ↓です。
// それぞれでHello()関数を呼び出す
american.Hello();
japanese.Hello();
indian.Hello();
korean.Hello();
chinese.Hello();
russian.Hello();
german.Hello();
これは、以下のようなことを引き起こします。
- このような処理をもう一度したいとき、同じコードをもう一度書く必要がある。
- 単純にコードが縦長になる。
かっこ悪いし、こんな長々と書きたくないです。
またこのような処理がしたいとき、またこのコードを書かないといけなくなるというのが、よくない点でしょう。
例えば、もう一回この関数を呼び出すときに、
// それぞれでHello()関数を呼び出す
for (int i = 0; i < N; i++) {
human[i]->Hello();
}
こう書くのと、
// それぞれでHello()関数を呼び出す
american.Hello();
japanese.Hello();
indian.Hello();
korean.Hello();
chinese.Hello();
russian.Hello();
german.Hello();
どっちがいいですかという話です。
クラスが増えた分だけ、ポリモーフィズムを利用していない下のコードのほうが大変になります。
次にすべてのクラスに新たなメンバ関数Hoge()が増えた時を考えてみましょう。
単純に考えてください。以下の二つのコードどちらがいいと思いますか?
// それぞれでHello()関数,Hoge()関数を呼び出す
american.Hello();
american.Hoge();
japanese.Hello();
japanese.Hoge();
indian.Hello();
indian.Hoge();
korean.Hello();
korean.Hoge();
chinese.Hello();
chinese.Hoge();
russian.Hello();
russian.Hoge();
german.Hello();
german.Hoge();
// それぞれでHello(),Hoge()関数を呼び出す
for (int i = 0; i < N; i++) {
human[i]->Hello();
human[i]->Hoge();
}
圧倒的に下のほうが見やすいですし、簡単ですよね。
このように記述量が減ることで、修正が加えやすくなります。
大規模開発の際は、あとから変更する場面が多々あるので、修正がしやすいことに越したことはないでしょう。
もう一度になりますが、このような書き方ができるのは、呼び出した関数が呼び出し元のオブジェクトに適した振る舞いをしてくれるからです。
そしてこの当たり前の特徴こそがポリモーフィズムなのです。
【もっと早く知っておけばよかった...。】情報系を学んでいる学生におすすめのサービス!
おすすめのオンライン学習サービス一覧!【基本無料・超初心者~上級者向けまで】
プログラミングやコンピューターサイエンスを効率的に学ぶには、オンライン学習サービスを利用するのが良いでしょう。
というより、使わなきゃ勿体ないですよ!
基本的に無料のサービスが多いですし、月額制のサービスでも1,000円~3,000円程度とかなりリーズナブルです。
オンライン学習サービス | おすすめ度 | 対象者 | 特徴 |
---|---|---|---|
Progate | 超初心者 | プログラミング入門・基本無料 | |
Udemy | 初心者~中級者 | 豊富な動画教材・セールでお得・教材購入 | |
侍エンジニアPlus | 初心者~中級者 | 現役エンジニアに質問できる環境・月額制 | |
Paiza | 初心者 | 競プロ入門・就活/インターン・無料 | |
ドットインストール | 初心者 | 動画教材・成果物ができる・基本無料 | |
Recursion | 初心者 | コンピュータサイエンス基礎・基本無料 | |
AtCoder | 中級者~上級者 | 競技プログラミング・アルゴリズム・無料 | |
Kaggle | 中級者~上級者 | AI・データサイエンス・競プロ・英語・無料 |
情報系を学んでいる学生におすすめなオンライン学習サービスに厳選しました。
ぜひ気になったサービスを始めてみてください!(その一歩が、1年後や2年後にものすごく大きな一歩になっているはずです。)
僕が実際に使ったのは、Progate➡Paiza➡AtCoder➡Udemyです。Kaggleもちょっとだけ。そのほかのサービスもとても魅力的です。
レバテックルーキー【ITエンジニアを目指すならここが最強】
レバテックルーキーは、ITエンジニア志望の学生におすすめの就活エージェントです。
レバテックルーキーのサービスを受ける条件は以下の2点です。
- 大学生・大学院生・専門学生・高専生・短大生である【文系・理系・情報系は問わない】
- ITエンジニア志望・もしくは興味がある
この条件に当てはまる方は、ぜひとも早めに登録することをおすすめします。(就活は早めにはじめると超有利になります。)
\ カウンセリング~内定まで"全て無料"! /
実際に僕もレバテックルーキーで最終内定を決めました。質の高い企業紹介と就活サポートが魅力の最強就活エージェントです。(ガチでオススメ!)
レバテックカレッジ【大学生専用のプログラミングスクール】
レバテックカレッジは、大学生・大学院生専用のプログラミングスクールです。
- プログラミングを学んだことがない。授業は受けたが、スキルに不安がある。
- 短期間で、Web企業に求められるレベルのスキルを習得したい。
- 大学に通いながら、就職活動を進めながら、並行して自分のペースで学びたい。
こういった方におすすめのプログラミングスクールです。
本気で学ぶならプログラミングスクールが効率的です。学生のうちに実務レベルのスキルを身に着けられれば、希少性の高い人材になれます。
オブジェクト指向のポリモーフィズム|まとめ
理解や解釈が難しいポリモーフィズムですが、私も最初理解に苦しみました。
いろんな記事を見てみたり、直接触れてみたりすると理解できるのではないかと思います。
またメリットなどは個人的な見解も含んでいますので、実際にプログラミングしてみてここは違うんじゃないと思うこともあるかもしれません。一つ参考程度に見てください。
この記事はプログラミングを学び始める方向けに作っていますので、これからプログラミングを始める方に少しでも役に立てれば、参考にしてもらえればと思います。
当ブログでは、こういったプログラミングに関する解説記事を多数執筆しております。
おすすめ記事を張っておきますので、ぜひ他の記事も見ていってください。
以上、「ポリモーフィズムとはなにか?超わかりやすく解説します!」でした!
最後までご覧いただきありがとうございます。