ショートカット
ファシリテーター × あり方
コーディングの向こう側
Hello, ANOTHER world!
オブジェクト指向のはなし
プログラミングのはなし
C言語実力診断クイズ
eSkillBooks
オブジェクト指向のはなし

クラスの多様性

導入

世の中に存在するオブジェクトの多様性を効率的に表現するためには継承だけでは不完全です。そこで、インターフェイスと実装をクラス階層中の別の場所に配置する仕組みが必要になります。

用語
このトピックでは次の用語を覚えます:
  • ポリモーフィズム、多態性、多様性、多相性 (polymorphism)
  • オーバーライド (overriding)
解説

「犬」「猫」「猿」クラスは「動物」クラスを継承しているとします。すると例えば、「呼吸する」という機能は「犬」「猫」「猿」すべてに共通のものなので、「動物」クラスで定義されます。

それでは、「鳴く」という機能はどうでしょうか?「鳴く」という行為は「犬」「猫」「猿」どれも似ています。しかし、鳴き声は全く違います。「犬」クラスのインスタンスに「鳴け」と命令した場合(つまり「鳴く」メソッドを実行した場合)は「わん!」と鳴くでしょうし、「猫」クラスのインスタンスなら「にゃ!」と鳴くでしょう。そこで、それぞれのクラスについて、共通の目的と独自の挙動をもつメソッドを定義する必要があるわけです。このようなメソッドはクラス階層のどこで定義されるべきでしょうか?

  • 「鳴く」というメソッドは「犬」「猫」「猿」どのクラスのインスタンスでも実行可能でなければなりません。だとすると、「鳴く」メソッドは「動物」クラスで定義されるべきもののように見えます。
  • 一方鳴き声は「犬」「猫」「猿」各クラスで異なります。だとすると、「鳴く」メソッドは「犬」「猫」「猿」それぞれのクラスで定義されるべきもののように見えます。

もっと深く観察しましょう。

「鳴く」というメソッドが「犬」「猫」「猿」どのクラスのインスタンスでも実行可能であるということは、このメソッドに関して、「犬」「猫」「猿」の各クラスが同じインターフェイスを持っているのだということです。一方、鳴き声が「犬」「猫」「猿」各クラスで異なるということは、「鳴く」メソッドの実装は共通ではないということです。

つまり、インターフェイスは「動物」クラスで定義し、実装は「犬」「猫」「猿」クラスで定義するのが自然です。

インターフェイスが「動物」クラスで定義されると、そのサブクラスである「犬」「猫」「猿」クラスのインスタンスを扱うときに、それが実際にどのサブクラスに属するのかを知る必要がなくなります。それがどのクラスのインスタンスであろうと「動物」インスタンスの一種なので、「動物」クラスで定義されている「鳴く」メソッドを共通的に実行できるのです。そしてインスタンス自身は自分がどのクラスに属しているか知っているので、自分専用の実装を使用して鳴き声を出します。

このように、インターフェイスがひとつでも、オブジェクトが属するクラスによって挙動が変わる仕組みのことをポリモーフィズムと言います(多態性・多様性・多相性などと訳される場合もあります)。ちなみに形容詞はポリモーフィックです。この仕組みが、実は、オブジェクト指向の要です。

ポリモーフィズムの目的を一言で表現すると「規格化」です。例えば単3乾電池を想像してみてください。これは規格ですね。規格を満たしていれば、どんな電池でも(アルカリでもマンガンでも)同じように使用できます。しかしそれぞれに特徴があるわけです。「単3乾電池」がスーパークラス、「単3アルカリ乾電池」と「単3マンガン乾電池」がサブクラスだとすると、「電圧を発生させる」というメソッドはポリモーフィックです。

規格化によって、オブジェクトは交換可能になります。コンポのスピーカーを自由に選ぶことができたり、SCSI 機器をつなげることができたり、コンセントにいろいろな電化製品がつながったりするのは、みな規格化の恩恵であり、ポリモーフィズムです。

C++ や Java では、スーパークラスにデフォルトの動作を実装しておき、必要なときだけサブクラスで独自の実装をすることができます。例えば「食べる」というメソッドは「動物」クラスの多くのサブクラスで共通の実装を利用できますが、「アリジゴク」クラスは少し変わっています(アリジゴクは体液を吸い取るのです、ああ気持ち悪い)。そこで、「アリジゴク」クラスでは共通の実装をキャンセルして、独自の実装に切り替えることになります。このように、特定のサブクラスでだけ実装を書き換えることをオーバーライドと言います。オブジェクトを扱うときに、オーバーライドされているかどうかを気にする必要はありません。一度規格化されたインターフェイスは不変だからです。

(「オブジェクト指向のはなし」は1999年2月から2000年4月にかけて作成されたコンテンツです。)