クラスと継承

構造化プログラミングは、段階的作成法に基づいて、階層的な抽象化を関数や手続きにて行って、順接・分岐・繰り返しの3つの構造を組み合わせて推し進めるプログラム作成技法でした。

しかし、この技法を用いて作成したとしても、プログラム作成後の仕様変更には多くの労力が必要になります1。例えば、既に完成したプログラムで、ある関数の引数の数を変更しなければならないときを考えてみてください。

明らかに変更する関数は別の関数で利用されているはずです。とすると、変更した関数が関係する全ての呼び出し元関数にも変更を加えなければならず、つまりプログラムにおいて1つの変更は大なり小なり他の関数(モジュール)に波及してしまいます(図1)。

あるモジュールでの変更の波及イメージ

図1:あるモジュールでの変更の波及イメージ

そしてこうした変更は往々にして、プログラム開発の最中に多発します!

プログラマの労力を減らすために、できるだけ、このような変更の波及は抑えられるべきですよね。

1967年にオーレ・ヨハン・ダールとクレステン・ニゴールはプログラミング言語Simula 67を開発しました。

Simula 67では、こうした変更の連鎖を避けるために、システムの構成要素おのおのが独立したプログラムとして作成でき、なおかつシステムの他の部分とはまったく、あるいはほとんど関わり合わずに修正できる構造として、クラスと呼ばれるプログラム構造を初めて導入しました[7][9]2。 Simula 67のプログラムは、時々刻々と変化する動的なシステムとして、より高度な概念、すなわち何らかの意味を持つ概念と対応付けられたプログラムの構造(図2)、を階層的に組み合わせることで構成します。

プログラム上で再現できそうな概念と階層のイメージ

図2:プログラム上で再現できそうな概念と階層のイメージ

この概念と対応付けられたプログラムの構造をクラスと呼んだわけです。

そして、このクラス構造を階層付ける方法が、継承(inheritance)と呼ばれる方法です。

この節では、オブジェクト指向プログラミングを構成する要素である、クラスと継承について触れていきます。

1

もちろん、プログラムの構造化手法を提唱したダイクストラは構造化をする上で、修正(修整)の影響を受ける箇所は既によく分離されているべきであると述べているし、段階的手法を使って、関数や手続きなどで層状に形作られた構造は分割統治的であるから[7]、ある程度は構造化手法でも解決可能な問題ではあります。しかし、構造化手法においては、ダイクストラの言う関数や手続きをつなぐインタフェース(データの表現)の有効範囲が存在し[7]、この有効範囲を超えた場合はこの限りではありません。

2

Simula 67で導入された時点では、``オブジェクト指向''と呼ばれる単語はありませんでした。同年に、1970年代にSmalltalkと呼ばれるオブジェクト指向プログラミング言語を開発したアラン・ケイが初めて使ったとされています [11]。

[7]: E.W. Dijkstra, C.A.R. Hoare, and O.J. Dahl, ``構造化プログラミング'', サイエンス社 (1975)

[9]: B. Meyer, ``オブジェクト指向入門'', アスキー出版局 (1990)

[11]: Dr. Alan Kay on the Meaning of "Object-Oriented Programming" | Userpage Freien Universität Berlin (20/07/02 閲覧)