オブジェクト指向とはなにか
日常生活の中のオブジェクト
私たちの身の回りには、自分で直接できることと自分では直接できないこととがあります。朝おきて何気なく読む新聞も、新聞社という組織が作り、近くの販売所が毎日届けてくれます。私たちが新聞を読むときには、誰がどのようにして作っているかを知る必要はありません。
また、あなたがエレベータに乗るときも、あなたは自分のいる階でボタンを押せばいずれエレベータがやってくると期待しているのです。それは、世の中にあるエレベータという乗り物がおおむねその様な動きをしていることを知っているからです。
駅まで行き、電車に乗る場合でも同じです。電車は、どこかの鉄道会社が作ったダイヤに従って動いているのです。あなたが、どの電車はこのように動きなさい、と規定するわけではありません。
通りでタクシーを拾う場合もそうです。あるタクシーは客待ちをしており、また、あるタクシーは街の中を流して客を探しているでしょう。しかし、タクシーを利用するときに、すべてのタクシーがどのような動きをしているかを知らなくてもよいのです。しかも、たいていは、目的地までの道順をあなたが知らなくても、目的地にたどり着くことができます。
私たちひとりひとりが個人で知り得る知識や個人で直接行える事柄には限りがありますが、それにもかかわらず私たちがさまざまなことをなし得るのは、社会のしくみそのものが、私たちの意志とは無関係に、ある一定のルールにしたがって自立的に動いているからなのです。
エレベータも電車もタクシーもその使い方さえ知っていれば使える便利な「もの」なのです。これをオブジェクトと呼ぶことにしましょう。
さて、今度はソフトウェアの世界のことを考えてみましょう。普通のソフトウェアのシステムの世界で何かやろうとするときに、ひとつの仕事をサブルーチン(手続きの流れを記述したソフトウェアの構成要素)という形で記述することがあります。しかし、このサブルーチンは私たちの世界の中のエレベータや電車のようなシステムにはなっていません。なぜならサブルーチンは、それを使うときになって初めて生成され、それ以外のときには存在しないからです。
ソフトウェアの世界でエレベータに乗るということを考えた場合、いったいどのようなことになるのでしょうか。従来のソフトウェアの世界では、まずエレベータのサブルーチンが初期化されます。初期化に従って1階にいるとか10階にいるとかが決まり、サブルーチンはその状態に従わなければなりません。つまり、エレベータそのものの動きを使う人が知っていなければ、ソフトウェアの世界ではエレベータを使うことができないのです。また、既存のサブルーチンを寄せ集めて何かをするということもできず、何かをしたいときは新しくサブルーチンを作って初期化して使わなければならないのです。
果たしてこのやり方は本当に便利なのでしょうか。ソフトウェアの世界も大きくなってくると、プログラムを細部まで把握して管理することが困難になってきます。もし各サブルーチンが、現実の世界の中のエレベータや電車のように、自分自身を管理しているオブジェクトであったらどうでしょうか。
この場合には、各オブジェクトの使い方さえ把握していれば、それらの動き(規定されたルール)について細かく知らなくても各オブジェクトを使うことができます。ソフトウェアの世界でもオブジェクトが使えれば私たちの日常生活のようにシステムが構築でき、私たちにとっては非常に使いやすいシステムにすることができるのです。
新しいパラダイム
人間の知的能力にはさまざまな側面があります。新しいものを作り出す創造的な能力、機械には不得手な言語理解やパターン認識の能力、数学などで要求される論理思考能力などさまざまです。日常生活の中では、私たちの思考や発言はいつも論理的であるとは言えません。むしろ情緒的で概念的でかなりあいまいなものです。実は論理的思考を長く続けることはかなり骨の折れることと言えるのです。
いままでのプログラミング言語はコンピュータの動作ルールに依存した特殊ともいえる論理一辺倒のものが大部分で、プログラムを組む際にも特殊な論理的思考能力が要求されています。人間がプログラムを組むときにエラーが発生し、デバッグが余儀なくされるのは、人間がこのような論理的思考を長く持続していくことを得手としていないことに起因しているといえるでしょう。
では、ソフトウェアの世界をもっと、人間の側に近づけることはできないでしょうか。コンピュータに何かをさせようとするとき、従来のプログラミング言語では、コンピュータの動きにそって個別の事象を記述しなければなりませんでした。つまり、先ほどの例を用いれば、エレベータに乗りたいときエレベータの設計・製造から起動方法に関する記述まですべてを行わなければ、エレベータに乗ることはできませんでした。
しかし、本来の目的はただエレベータに乗りたいわけですから、私たちの世界のように、エレベータに関する設計や製造などは考えずに、誰かが作っておいてくれているものを利用すればそれを呼ぶだけでエレベータに乗ることはできるはずです。また、こうしてエレベータに関して記述されたものは他のところでも利用できるのです。
このようなソフトウェアの世界が実現できたらどんなに素晴らしいことでしょうか。実はこれがオブジェクト指向が登場した理由の1つといえるのです。
では、もう少し具体的にソフトウェアの世界での「オブジェクト」はどのような存在であればよいのかを考えてみることにしましょう。それは、端的に言うならば、データの部分と手続きの部分が切り離されずにひとつになっているものと言えます。
実は現実の世界ではこの方がずっと自然な考え方です。これだけではわかりにくいので先程の例で考えてみましょう。
エレベータの場合、エレベータの箱(人が乗る部分)や各フロア、各フロアにあるエレベータの扉がデータとなり、モーターを回すとか、扉を開閉するという操作が手続きになります。データと手続きが一緒になっていると自己管理能力が出てきます。ソフトウェアについても、もっと人間に近いレベルで考えたほうが便利です。そのアプローチのひとつがオブジェクト指向なのです。これは、いつも人間が物を見ている見方と適合するものなのです。
なぜオブジェクトか
オブジェクトという形にしておけば、ソフトウェアのモジュラリティが非常に良くなります。このモジュラリティが良いと言うことは、たとえて言うと、1つのシステムが積み木のように1つ1つを組み合わせてできているということです。モジュラリティが良くなると、メンテナンスがしやすくなります。古くなって調子の悪い積み木は、その外形が同じであれば、取り換えることができます。
このことはソフトウェアを財産化する道につながるのです。なぜなら、誰かが作った積み木をそのまま、他の人が使ってシステムを作り上げることができるからです。最高の品質を持つ積み木は、いろいろな人がシステムを作るときに利用することになります。これが財産になるのです。ここでは、このことについて、もう少し詳しく見ていきましょう。
プログラムの部品化
これまでのプログラミング言語では、あるシステムを記述していく場合、いわば何もない状態から始めなければなりませんでした。プログラムを作るたびに、同じような目的のサブルーチンを作らなければならなかったのです。
しかし、オブジェクト指向型言語では、それまでにプログラムされたことがすべて蓄積として残されます。オブジェクトというデータ構造(データ+手続き)のために、部品として何度でも利用できるのです。
つまり、オブジェクト指向型言語におけるプログラミングでは、それまで培われてきたプログラムを部品として付け加えたり取り除いたり、また改良を加えたりすることが自由にできるのです。
この部品は、ハードウェアの部品と違って、部品と部品の結合がロジカルなものであるので、1つの部品が同時にいくつもの部品と結合することができるわけです。部品化が可能であると以下のようにいくつもの利点が生まれます。
メンテナンスの容易性
よいソフトウェアは長く使われます。しかし、長く使っている間には手直しが必要になります。手直しの仕方もこれまでのやり方は、パッチワーク的なやり方で、つぎあてをしていました。
しかし、どんなによいソフトウェアでも、このような直し方をしているとしだいに複雑になってしまい、最後には手直しをするくらいなら新たにプログラム全体を作り上げるほうが楽である、というようなことになってしまいます。そんなことをしていては効率が悪いので、もっと本質的に異なるプログラムを作っておくことが必要なわけです。
たとえばデータベースの場合、最初にデータのフォーマットを決めてしまったとします。そのデータ構造にアクセスするような仕組みを今までのソフトウェア・システムで書いたとすると、そのカラム数を変えたくなったときに、その部分を変更すると、そのデータをアクセスしているソフトウェアをすべて書き換えなければならなくなりました。しかし、部品化しておけば、その部分だけを取り換えるだけでよいのです。
それでは、このような部品化はBASICやFORTRANのような手続き型言語ではできないのでしょうか。ソフトウェアを大きな部品から小さな部品へと順次細分化しながら作ってゆくトップダウン設計の手法を使えば、部品化はできます。オブジェクト指向ではなくてもモジュール化しておけば、上のルーチンとは関係なしに必要な部分だけ変えればよいようにできるのです。
しかし、手続き型言語には問題があります。では、どのような問題があるのでしょうか。
手続き型言語でソフトウェア・システムを作るやり方としては、モジュール化するやり方とモジュール化しないやり方の2通りがあります。モジュール化すると速度が遅くなるので、ある部分はモジュール化しないでおきましょうということもできます。そして、一度このようにモジュール化されていない部分がソフトウェア・システムの中に組み込まれてしまうと、あるサブルーチンが勝手気ままにあるデータを使用するという現象を起こし、そのシステムは全体としてみた場合、モジュール構造を持つことについての保証がまったくなくなってしまうのです。
ハードウェアの能力が低く、ソフトウェア・システムの処理速度が問題にされた時代には、モジュール化されずに作られたものが多かったようです。考えようによっては、手続き型言語には柔軟性があるということにもなりますが、実はこれがシステムに悪影響を与えることがあるのです。
オブジェクト指向言語の場合はどうでしょう。オブジェクト指向型言語では、必ずモジュール化しないとプログラムが書けないのです。そこがオブジェクト指向型言語と手続き型言語の大きな違いです。
もちろん、質の高いプログラマーはどのような言語を使用しても、ソフトウェアをモジュール化して、後の変更に対して強いシステムを書くでしょうが、入門したばかりのプログラマーではそういう書き方が必ずしもできるわけではありません。ここに落とし穴があるわけです。たとえば、作業を分担してプログラムを作った場合、ある部分はモジュール化されているのに、別の部分はモジュール化されていないということが起こります。
オブジェクト指向型言語では、モジュール化しないとプログラムが書けないということが、メンテナンスのしやすさを保証しているのです。メンテナンスしやすいということは、ソフトウェア・システムの作り方にも大きな変革をもたらしました。これが次に述べるプロトタイピングです。
プロトタイピングという手法により、これまでの要求仕様定義のように固定的な方法から、もっとダイナミックに仕様を変更していける道が開けたのです。そして、これを実現したのがオブジェクト指向型言語なのです。
オブジェクト指向分析/設計
「ソフトウェアについても、もっと人間に近いレベルで考えたほうが便利です。」と述べました。
これは実装(製造)だけにとどまらず、前工程である分析/設計においても同じです。ソフトウェアの開発とは、現実世界をモデル化し、さらにそのモデルを計算機世界にマッピングする作業といえます。
現実世界をモデル化する(何を作るかを定義する)作業がすなわち分析、モデルの計算機世界へのマッピング(どう作るかを決定する)作業が設計および製造です。であれば、現実世界から計算機世界までの一連の変換作業を「人間が物を理解するやり方」に近い、オブジェクト指向で通すのが自然です。
従来の設計手法では、機能モジュールに分割し、そしてそのそれぞれをブレークダウンしていました。この手法は機能を骨組みとしたやり方です。作成された設計書あるいはコードは機能を柱とした構造を持っています。ソフトウェアの変更や改造はほとんどの場合機能の変更/改造ですから、場合によってはソフトウェアの構造を根幹から揺るがすことになりまねません。
オブジェクト指向分析/設計では、そのシステムを構成する「もの」とその関連が骨組みとなります。機能的な変更/改造が「もの」そのもの、あるいは「もの」の間にある関連を大きく揺さぶることはまれです。オブジェクト指向によるソフトウェア開発が変更/改造に強いといわれるのは、機能を骨組としていないからです。
ソフトウェア開発の前工程、すなわち分析や設計におけるオブジェクト指向はどんな意味を持っているのでしょうか。
もちろん実装の過程でオブジェクト指向型言語を使用する場合においては、前段階からオブジェクト指向に基づいた分析/設計を行っておけばアイデアと実装とのギャップを小さくできる、言い換えれば「アイデアがそのままコードになる」境地に近づくことができるのはいうまでもないことですが、従来の手続き型言語で実装するにしてもオブジェクト指向分析/設計のメリットはあると考えます。
それは、オブジェクト指向型言語が実装面での再利用性を高めると同様に、オブジェクト指向分析/設計が分析/設計フェーズでの再利用に有効なのです。
たとえば「時計」を設計したとしましょう。時計には「時刻合せ」と「時を刻む」という大きな機能があります。時計の満たすべき基本的な条件と機能とをオブジェクト指向分析/設計できちんと定義しておけば、その後「タイムレコーダ」を設計する際に、時計の設計書が再利用できます。すなわち、「タイムレコーダは時計の一種である。基本的な条件/機能は時計の設計書を参照のこと。タイムレコーダを実現するにあたり、時計とは異なる項目、および追加すべき項目を以下に述べる」などと設計書の冒頭に書き、時計との差分/追加分のみを記述すればタイムレコーダ設計書のできあがりとなるならなんて楽でしょう。
いわば設計書のライブラリ化が可能となります。
C++学習のために
オブジェクト指向と言う言葉がパソコン世界のいたる所に浸透してきておりその概念を知っていないと置いていかれると言う状況になってきました。
多くの資料がありプログラミング上での勉強の資料に事欠きませんがプログラミング上での資料ですからパソコンの世界でのオブジェクトとなると対象が広いだけに曖昧模糊としてつかみどころのないものになっています。
特定の言語に依存してしまう「オブジェクト指向言語」の資料ではその言語自体をマスターしていなくては理解できず言語を理解するにはオブジェクト指向の概念を理解していなければならないというパラドックスで初心者にはお手上げ状態になっています。
さて、プログラミング用語であると思われるオブジェクト指向をアプリケーションを使う側で知るべきかという点でオブジェクト指向の何たるかを知っているのと知らないのとでは天国と地獄の差が出てきます。
ですのでこの原稿では本来のプログラミングと言う観点からはピントのずれている箇所もありますし、オブジェクト指向を取り入れているアプリケーション、言語は列挙するだけで膨大な数になりその中で使用される用語も大同小異と言ったものから小同大異と言えるものまでありますのでこの原稿では広く使用されている用法を表記解説しますことをまずお断りします。
そしてオブジェクト指向の概念を解説するという大それた考えはまったくなく、おじさんたちへの理解の一歩を踏み出すためのきっかけとなれば幸いとの考えで書き連ねますからこの原稿の後それなりの本格的オブジェクト指向の書籍を読む事をお薦めいたします。
ではさっそくオブジェクト指向の勉強における最低限の知識習得にはいります。
まずオブジェクト指向全体に触れなくてはなりません、結論から言うと「オブジェクトを中心にする考え方」で今までの操作手順を中心にする考え方は手続き指向と言います。
オブジェクトと言う意味は「(知覚できる)物,又は物体」と言うことですが、使用方法から言うと広義の意味と狭義とがあります。
このことをわかり易く解説しますと
ディスプレイの画面上にある広さを持つ枠(土台)がありその中にボタンが一つ配置されボタンをマウスカーソルなどで押すと簡単なメッセージを表示すると言う簡単なプログラムがあるとします。
この例でボタンが表示されている土台部分をフォームと言います、そしてフォームもボタンもオブジェクトで、「ボタンが」押されるなどの行為に反応するプログラムがボタンの部分に関連して書き込まれていない限り「単にボタンを表示する」だけのものです(ボタンなどのパーツと言って良いものを狭義の意味でのオブジェクトと言うことがおわかりだと思います)
ボタンが押された時に実行されるものをメソッドと言いますがプログラムにおける「手続き」と言う意味です、このメソッドがボタンと言うオブジェクトに書き加えられことでプログラムが完成されます。
Visual BasicCやExcelなどを学んでいる方には周知のことですが、これらの言語やアプリケーションでは基本になるフォームもボタンも最初から用意されていますのでフォーム上にボタンを配置してボタンを押したら表示する文章をボタンに書き加えるだけで簡単にプログラムが完成します。
ぐだくだと頭からフォームやボタンの形態の記述はいりません、なぜこんな簡単なことでプログラムが完成するのでしょうか、それはオブジェクト(各パーツ)が全て独立しているからにほかなりません、「知覚される物」がオブジェクト指向の基本概念です。
先の「物又は物体」を広義でオブジェクトと言うのがおわかりと思います。
独立したオブジェクトがただ単に独立して動作するだけではなんのメリットもありませんし単純作業しかこなせないものでしかありません。
独立しつつも複雑な連携を実行するが、それをユーザーに感じさせない。これが求められているのです。
そのための考えが
という3つの概念です。
カプセル化
カプセル化とは「データとルーチンが一体化されている」ことを指します。プログラム言語ではレコード型(C言語などでは構造体となります)の定義は「異なったデータをひとかたまりとして扱う」と言う点でした、この異なったデータと言う部分を「データの代わりにメソッドや関数をも記述できる」としていただければ理解できると思います。
データとメソッドが単に一緒になっていればよいのではなくデータに対する操作方法がすべて記述されていなくてはなりません、ということはデータはメソッドで保護されメソッドを通してのみ操作できるということが必要になります。
データとメソッドを一つのものとして扱いさらにはデータにアクセスするにはデータと一体化されているメソッドを通してしか接することができません、これによってデータの内容を知らなくてもメソッドの使い方さえ分かればデータの操作ができます。
データの安全性が高まるのです、実にシンプルな考え方で、これ以上何物でもありません。
カプセル化と言う言葉に惑わされてはいけません基本理念は「データの保護」と言うことです、データの保護のためにメソッドが一緒にされ、さらに保護のためにメソッドを通さなければならないのです。
継承
カプセル化の次は「継承」です、継承とは読んで字のごとく「継承=引き継ぐ」と言うことになります、なにがなにを引き継ぐかと言いますと今あるオブジェクトのデータとメソッドを別のオブジェクトが引き継ぎオブジェクト間で上位、下位と言う関係を作ることを言います。
元になるクラスを「BaseClass」と言いそこから派生したクラスを「DerivedClass」と言います。
ここで言うクラスはプログラム言語によって若干の違いがあります、カプセル化された一単位のデータとメソッドを指す考え方、そしていくつかの似通ったオブジェクトをまとめてクラスという表現をする考え方で通常こちらの考え方を「クラス」として使います。
似通ったオブジェクトをまとめて表現することをオブジェクト指向用語風に書くと
「機能や性質に共通点があるオブジェクトの総称」となります。
例えとして「乗り物−自動車−乗用車−『の中の大衆車クラス』にはサニー、カローラ、シビック等がある」と言う言い回しでこの場合のクラスと言う表現がわかると思います。
そしてこのクラスは階層構造を作る事が多く、オブジェクト指向の参考書などでは「系図」などとして取り上げられているますので簡単に理解できると思います。
さて継承は上位の特徴と言えるものを下位が引継ぐと言うことですが逆に言うと既にあるクラスを利用して新しいクラスを作ることができると言う事になります。
新たなクラスを作る場合、既に記述してあるクラスの機能を一々新たなクラス内で記述しなおすことは非能率でしかありません。
既にある機能を継承できれば新しい機能だけを継ぎ足すだけでいとも簡単に新たなクラスを作ることができることになります。
通常継承をインヘリタンスと表記しますが、この言葉自体はなんら意味を持ちません、単に継承を読み換えているだけと理解して下さい、ただし言葉上では単なる継承ですが機能上、自身のクラスに存在しないメソッドの実行を求められた時、上位クラスに定義されているメソッドの実行で代用する事を含んでいることに注意して下さい。
最初から設計をしっかりしておけばインヘリタンスを無理して取り入れる事もないのではと言う疑問も出てきますがインヘリタンスはオブジェクト指向における重要な要素となっていると言うことはそれなりの理由があっての事です。
ポットにミルと言う機能付け加えるだけでいとも簡単にミル付きコーヒーポットができます(物としては簡単ではないでしょうがが)ビデオカメラを継承してテレビと言う機能を付け加えれば新たな機種が出来上がります。
これらは物としての考えですがこれをプログラムなどに導入したと考えてください、オブジェクトで言うインヘリタンスの意味するところがおぼろげながら見えてきたはずです。
さらに便利なことに上位のオブジェクトで定義された機能を下位のオブジェクトで書き直すことができます、全て継承することもなく又継承したくない部分を書き換えてしまうことが許されておりそれをオーバーライド(override)と呼びます。
ここで継承=インヘリタンスをまとめますと
- 既にあるクラスを利用して新しいクラスを作る。
- 新しいデータやメソッドを追加できる。
- 上位のデータやメソッドを定義し直せる。
ということになります。
1と2は表裏一体の関係と言えます、新しいデータやメソッドを追加せずただ継承だけではなんら必要性が認められないからです。
3のオーバーライドもこの後で軽く触れる「多態性」では意味を失いますが現在は素直に受け取っていただいて結構です。
この便利なオブジェクト指向の特徴であるインヘリタンスも上位のクラスを一つしかもてないシングルインヘリタンスですのでマルチインヘリタンスに比べると不便と言えば不便です。
シングルインヘリタンスと聞きますと上位から下位まで一本の線でしかつながっていない直線構造の様に考えますが、シングルと言っても直系の上位クラスが一つと言う事で直系の下位クラスは任意の個数を持つことができます。
しかしインスタンスのラインが1本と考えるとわかりやすいので系図をもって説明していきます。
車 | | ←トランクリッドを取る ↓ ピックアップ・トラック | | ←荷台にルーフをつける ↓ バン・ワゴン | | ←四輪駆動にする ↓ RV | | ←ボディ鋼板を厚くする ↓ 軽装甲車
と、強引に現実の製品系列を無視していますがその意図は理解していただけると思います、すべての製品が自動車と言う機能を継承していますし途中で追加された機能も下位の製品では継承しています。
先のオーバーライドをこの図式で説明しますと「荷台にルーフをつける」で金属製ではなくキャンバス地にすると言った感じで機能を付け替える(オーバーライド)ことで感じがつかめるはずです。
インヘリタンスにおける直系上位は一つだけですが直系下位は任意の個数定義できますのでこの自動車系図を当てはめますと
上位 車 ┌───┤ ルーフを取る→| |←トランクリッドを取る ↓ ↓ オープンカー ピックアップ・トラック │ │ キャンバス→| |←荷台にルーフをつける ルーフ | ↓ | バン・ワゴン 四輪駆動→| | ↓ |←四輪駆動にする ジープ ↓ | RV スクリューを→| |←ボディ鋼板を厚くする つける | ├−−−┐ ↓ | |←砲をつける 水陸両用車 ↓ |←キャタピラに変える 軽装甲車 | | ↓ ジープは登録商標です 戦車
と言ったとこでしょうか、各名称は適当につけていることと下位の枝分かれが2つだけですが単なる紙面の都合だけですとお断りしておきます、しかし下へいくほど軍用の形態になっていくと言うのは不思議ですね車の機能から言ってスポーツカーと軍用車が両極の形と言う事なんでしょうか。
閑話休題
この例でも全ての下位は車と言う機能をインヘリタンスしていますことがおわかりと思います。しかしこの個々の製品は外見上見分けがつきますがオブジェクトの概念から言えばその以前の機能は表面的にまったくわからないと言うことに注意してください。(もっとも最近の車は外見だけでは区別がつかないものが多くなっていますけど)
さらに多重継承としての概念が有ります、いままではすべて上からの継承は一つだけてしたが、例えばラジオカセットは別の観点から見るとラジオにカセットテープという二つの機能が継承され合体してできたものでラジオにテープレコーダーが付属したのではなく両方の機能が融和してできたものとみなす事ができます。
この例からも分かるとおり複数のクラスからデータやメソッド等を継承していることを「多重継承」と言いますが単なる言葉としておぼえておいてくださるだけでそれ以上は初級入門者には必要ないでしょう。
なぜなら多重継承を系図化すると
No1−−−−−−− | | | | No2 No3−−−−−−− | | | | | | No4 No5 No6 | | | | −−−−−−−No7ーーーーーーNo8 | |
と言う感じになります、この系図でNo8に対する直接の親(Base)はNo7とNo6になり両方のオブジェクトやメソッドなどがぶつかる場合がでてきます。
この様な場合に「なにをさせようとしているのか」「両方をさせようとしているのか」「両方の時どちらを優先させるか」などと言う問題が出てきます。
これらは非常に高度のテクニックと細心の注意が必要ですから初級入門者には難題となりますので言葉としてとどのようなものかだけを覚えておけばよいでしょう。
多態性
オブジェクト指向プログラムにおける最大の難所である多態性ですが、この拙文はオブジェクト指向プログラムの勉強ではなく「オブジェクト全体」の入門解説ですから深くは触れませんがある程度の事を知っていても損はないので軽く触れます。
多態性というまったくもって意味の通らない日本語のもとはポリモルフィズムと言う言葉でポリモルフィズムとはPolymorphismと書きギリシャ語のpoly=多くの、とplymorphism=意味の要素、が合わさってできた言葉で「同名異型」という意味です。
そして導きだされることは「異なる型に対して同名の操作を行う事ができる」となり逆の書き方をすると「異なる機能を持つ物が同じ名前をもつことができる」と言う事になります。
先のインヘリタンスでもメソッドで同じ名前を定義するオーバーライドということができましたしオーバーライドと同一の様ですがまったく違っております。
さきでのオーバーライドでは同じ名前を使うことにより上位クラスの機能は下位クラスの機能に書き換えられてしまいます、しかしポリモルフィズムにおいては同一の名前をつけても機能が書き換えられません。
「同一の名前でも機能が違う」
と言うことです
このことがどんなメリットがあるかと言うことは初級程度のプログラムではなかなか難しいところがありますが、構造化プログラムの特質である、ルーチンの部品化を突き詰めていく結果に出てきたのでは思われます。
すなわちプログラム上では必要となる知識ではあるが、単純にオブジェクト指向の入門と言う立場では特に必要がある言葉だろうか、と言う結論がでてしまう身も蓋もないことになります。
初級におけるポリモルフィズムの意味は
上位のクラスから下位のクラスまで一つの動作に同じ名前をつけてそれぞれのクラス内では別々の動作をさせる、そしてポリモルフィズムを実現するのがバーチャルメソッドで、仮想的に記述することによりそれらのメソッドの参照先をコンパイル時に決めず実行時に決めるとなります。
簡潔に言えばポリモルフィズムが「戦略」でバーチャルメソッドが「戦術」と言えます。