CTMCP 7章:オブジェクト指向プログラミング

 明示的状態を導入した計算モデルの上に構築された抽象とその利用について。特に、その意味定義・抽象の設計上の決断と他の計算モデルとの関係、使い方に関する注意、など。

要点

 前章で、明示的状態を導入することで増大する複雑さは、データ抽象によるカプセル化で抑制するのがよいということを見た。データ抽象の中でも値とその操作が一緒になったオブジェクトというスタイルを利用する。これによって、多態性が得られる。さらに、オブジェクト指向プログラミングは、継承という概念を付加することで漸増的な構築を可能にする。
 継承は、威力は大きいがかなり注意して使う必要がある概念である。共通の部分を括り出す可能性は増大するが、同時に、あるインターフェースの実装がプログラムの至る所にばら撒かれる。また、オブジェクトを理解するに際してその祖先も一緒に考えなければいけなくなり、プログラムの理解や設計の維持、デバッグが困難になることがある。
 オブジェクト指向プログラミングの追加したものは、計算モデル上のものではない。クラスは、ある値と操作のセットをラッピングした値を返す関数として、継承はクラスを入力としてクラスを出力する関数として考えられる。よって、高階プログラミングの一種である。オブジェクト指向プログラミングの追加したものは、どちらかと言えば、その抽象をどう設計し構文に組み込むか、という装飾にある(あくまで計算モデルの立場からの見方であり、実装は最適化を考慮する)。
 継承の見方は2通りあり、一つは型と見る見方、もうひとつは構造と見る見方である。ほとんどの場合において、型と見るべきである。これは、クラスは代替性(substitution property)を満たすべき、ということを含む。Aを継承したクラスBが代替性を満たすということは、Aに対して使える操作がBに対しても行え、その基本的な表明を満たすことである。

感想

 明示的状態を素直に使ったいわゆる手続き型のプログラミングと、オブジェクト指向のプログラミングの間に感じていたジャンプを解消できたのが良かった。手続き型にオブジェクト指向を追加する例としてCからJavaみたいなのを想定してしまうと、単純な装飾という以上に、1) 第一級の関数の追加、2) 名前値などによるセキュリティ機構の追加 というもっと根本的なレベルでの変化が混ざっていて、そこがジャンプを感じる原因だったと思う。
 Ozは動的な言語で、クラスもオブジェクトに対するメッセージ(メソッド呼び出し)も第一級なので、リフレクションや委任(delegation)などが自然に実装できる。ここで構築したオブジェクト指向システムは、広く使われている言語で言うとRubyに近い、と思う。C++, Javaなどのコンパイルを行う静的型付け言語が第一級のメッセージをサポートしてなかったり(C++)、多態性に制限があったりするのが性能やプログラムの保証上の理由であることを考えると、オブジェクト指向を純粋に理解するという観点からは動的で制限のない言語の方がいいのかなとか。