プログラミング言語には様々な便利な機能がありますが、あまりにも覚えることが多すぎて混乱してしまうことも多いでしょう。特にプログラミングの勉強を始めたばかりの頃は、似たような単語が登場すると、覚えるのにも苦労するものです。
今回はプログラミングを少し勉強していくと出会うことになるオーバーライドとオーバーロードという似た言葉について、それぞれの違いや使いどころについて解説しています。間違えやすいこの言葉ですが、中身はまったく違っているので、理解してしまえば意外と混同しなくなります。機能としても便利なので、是非この機会に覚えてみてください。
オーバーライドとオーバーロードの違い
オーバーライドとオーバーロードは、言葉こそ似てはいますが、中身は全く異なるものです。いずれもプログラミング言語の機能の一つで、現在使用されている多くのプログラミング言語でサポートされています。
どちらも「なくてはならない」ではなく、「あれば便利」というものではあるため、プログラミング言語によってはサポートされていないこともあります。有名な所では、Webなどを中心に広く利用されているPHPではオーバーロードはサポートされていません。
ここではそれぞれがどういった機能なのかを確認してみましょう。
オーバーライドは上書き
オーバーライドは、英語ではOverrideと呼び、クラスの派生先で基底クラスの関数・メソッドなどを上書きすることを指します。
この機能はオブジェクト指向に基づいたクラス設計においては非常に強力なもので、クラスを定義できるプログラミング言語ではほぼサポートされています。
定義の方法はプログラミング言語によって様々ですが、共通なのは派生クラスで同名の関数を定義することで、基底クラスの関数は外部から呼び出せなくなります。一方で、派生クラス内では基底クラスの関数を呼び出すことが出来るため、派生クラス内で「機能の追加」という挙動を実現することが可能となります。派生クラス側で追加機能だけを実装し、後は基底クラスの処理を呼び出すことで、共通処理と追加処理を、基底クラス・派生クラスで役割分担できることになります。
クラスを利用する側にとっては、同名の関数を呼び出すことで、派生クラスの追加機能の恩恵を受けることができることになります。バージョンアップなどで追加機能を提供する際などに、プログラムコードの変更量を抑える事にも役立ち、インターフェースの変更を伴わない修正は高い品質を維持しやすいでしょう。
オーバーライドを使わない選択ももちろん可能で、派生クラスで追加機能を実装したインターフェースを分ける場合には別名で定義し、同名で提供する場合にはオーバーライドを使うといった使い分けが可能です。
オーバーロードは多義化
オーバーロードは、英語ではOverloadと呼び、引数の異なる同名の関数を定義することを指します。日本語では多義化と呼ばれ、前述のオーバーライドと名称が似ているため、あえてこちらを日本語で呼称するようにしている人もいるようです。
この機能は先に紹介したように、PHPなどメジャーなプログラミング言語であってもサポートされていないこともありますが、あると便利な機能です。特に役割が同じ関数を同じ名前で定義できるというのは、プログラマーにとっても整理がしやすく助かります。特に複数人のプログラマーが関わっている場合などには、中身を読まなくても関数名から動作を理解することができるため、非常に便利です。
クラス設計においては、同様の機能を複数のインターフェースで外部に公開する場合、オーバーロードが許されているプログラミング言語では同名で、そうでない場合は別名で定義することになります。マルチプラットフォーム展開するソフトウェアのコンバート作業などでは、インターフェースの数だけ別名関数を用意しなければならなくなり、あわせて呼び出し側も修正することになるので、オーバーロードのありがたさを痛感することになります。
利用する側も、まったく同じ機能なのであれば同じ名前で呼び出すことができる方が理解しやすく扱いやすいため、サポートされているプログラミング言語では、積極的に活用していきたい機能の一つです。
オーバーライドの使いどころ
基本的には、クラス設計において基底クラスの提供する機能に変更を加える際に利用します。
プログラミング言語によっては、派生クラスでオーバーライドをするために、基底クラス側で関数へvirtualなどの修飾子が必要になる場合もあります。virtual修飾子は、指定した関数を仮想関数とし、派生クラスでのカスタマイズを可能とします。
またプログラミング言語にもよりますが、オーバーライドを強制するabstractという修飾子もあります。abstract修飾子を付けた関数は、抽象関数となり基底クラスでは実体を定義できず、派生クラスで必ず実体を定義しなければなりません。実体のないインターフェースを持った基底クラスは、クラス自体も抽象化されてインスタンスを生成できなくなります。デメリットが多いように見えますが、派生クラス側に実装を強制させる効果は、共通インターフェースを提供することに大きく貢献します。
abstractやオーバーライドについて詳しく解説している以下の記事も、是非合わせてご覧ください。
オーバーロードの使いどころ
オーバーロードはとても便利な機能で、個人的には頻繁に使いたくなる機能です。特にコンストラクタのオーバーロード(多義化)をすると、クラスのインスタンス生成を様々な形で行うことができるようになるのは、プログラムの可読性を高めることにもなり、非常に便利です。SDKやAPIなどで提供されていることも多いため、オーバーロードを意識せず利用している人も多いかもしれません。
オーバーロードがサポートされていないPHPでは、マジックメソッドという特殊な機能が提供されており、コンストラクタの多義化のような重要な局面では、その機能を使って疑似多義化のようなことができるようになっています。
色々な場面で役立つオーバーロードですが、典型的な例を一つ上げるとすると、画像の描画のようなシチュエーションでも活躍します。描画をする場所を、x座標,y座標で受け取るインターフェースと共に、x,yの座標を合わせて持った構造体やクラスなどをパラメータにとるインターフェースも同名で提供することが出来ます。利用する側は、その時点で持っている情報に合わせてパラメータを変えるだけで、同じ名前の関数を呼び出すことができるため、とても扱いやすくなります。
// 座標で指定
drawImage(x, y);
// 構造体・クラスで指定
drawImage(pt);
オーバーロードがない環境では、こういった局面では関数名を変えてそれぞれ定義することになります。パラメータのパターンの数だけ関数が生まれることになり、プログラムコードはどうしても煩雑になってしまいます。
プログラミングの機能を使いこなそう
プログラミング言語には様々機能があり、すべてを覚えて使いこなすのは簡単ではありません。特に最近のプログラミング言語は非常に多くの事が出来るようになっていることもあり、提供されている全ての事を網羅して覚えるというのは現実的ではないでしょう。
そんな中でも、今回紹介したオーバーライドやオーバーロードのような、各プログラミング言語に共通しているコアな機能についてしっかり覚えておきたいところです。特に、プログラマーとして能力を高めていきたいと考えている人や、将来システムエンジニアやプロジェクトマネージャーのような上流工程の役職を目指している人にとって、ソフトウェア設計で重要となる仕組みについては押さえておきたいところです。
グループでのプログラミング作業をしている人はもちろんの事、個人でプログラミングを行っている人でも、オーバーライドやオーバーロードのようなプログラミングの機能を使いこなし、より安全で便利なプログラムを制作することを心がけていきたいものです。
コメント