コンテンツへスキップ

オブジェクト指向の哲学:オブジェクト指向プログラミング

先週から書いております「オブジェクト指向の哲学」、以下は第1章に相当するところです。


1. オブジェクト指向プログラミング

1.1. ソフトウエアオブジェクトのもつ二つの意味

オブジェクト指向プログラミングにおける「オブジェクト」は、内部構造をもつデータの意味で使われています。例えば、"Smalltalk" (鈴木則久著、産業図書:1986)では

オブジェクトとは内部状態を記憶しておくためのデータ構造(これをインスタンス変数と呼ぶ)と、それをアクセスする手続き(これをメソッドと呼ぶ)からなっている

と定義しています。

もう一つのオブジェクトの定義として、

オブジェクトとは記憶領域のことである

という定義が "注解C++リファレンスマニュアル" (エリス、ストラウトソトラップ著、足立高徳、小山裕司訳、トッパン:1992)にあります。これは先に掲げた定義と大きく異なっています。

私がここで「オブジェクト指向の哲学」などと題して文章を書いているのは、この二つのまったく異なる定義が、本稿の着想の出発点となっているからです。

まず第一に、この二つの定義はどちらも間違いではありません。プログラマはオブジェクトを内部構造をもつデータとして扱う一方、いったんプログラムが計算機にロードされますと、オブジェクトは記憶装置のある領域を占めることになります。この二つの定義に何の矛盾もなく、オブジェクトの置かれた状況が違うために、異なる見方をされただけです。すなわち、前の定義はプログラマがプログラムを作成したり、読んで理解する状況を想定してのオブジェクトの定義であり、後の定義はプログラムが計算機にロードされた状況を想定してのオブジェクトの定義です。

ソフトウエアの開発に際しては、この二つの状況に対応した、二つのファイルが用いられます。

一つはソースファイルで、内部構造をもつオブジェクトが記述されており、プログラマはソースファイルを書き下すことでプログラムを作成し、ソースライルを読むことでプログラムを理解します。

もう一つはバイナリファイルで、計算機の主記憶にロードすべきビットパターンが、バイナリファイルに記述されます。

ソースファイルとバイナリファイルは、見た目はまったく異なるファイルですが、バイナリファイルはソースファイルをコンパイラで処理することで機械的に作り出すことができます。すなわち、この二つのファイルは、表現は異なりますが、その意味する内容は同じである、ということができます。

オブジェクトの定義のこの二面性の興味深い点は、デカルトのいう「拡張」と「観念」に、オブジェクト定義の二つの面がきちんと対応ていることです。

記憶装置における領域」は「エネルギー粒子の広がり」に対応します。エネルギー粒子の広がり、という表現はデカルトの表現ではありませんが、デカルトが第三省察で蜜蝋を例に取り上げて説明している「延長(ひろがり)」を、私流に現代風に言い直した表現です。物理的世界は、均質なエネルギー粒子の相互作用で成り立っており、多数の同じメモリーセルからなる計算機の主記憶装置と類似しています。ソフトウエアオブジェクトは、計算機の内部では、主記憶装置の特定の領域を占めますので、これを広がり(拡張)と呼ぶことも不自然ではないでしょう。

一方で、「内部構造をもつデータとしてのオブジェクト」は、人がこの世界に存在するさまざまなものに対して抱く「概念(デカルトによれば観念)」に対応します。内部構造をもつデータとしてオブジェクトを捉えるのはプログラマであり、そこに精神的な働きが介在します。オブジェクトの構造は、人がプログラムを理解する際にのみ意味をもち、プログラムが機械語に翻訳され、計算機にロードされた後には、主記憶の内部にオブジェクトの論理構造を見出すことはもはやできない相談です。

ソフトウエアオブジェクトに対する二つの見方は、オブジェクトの二面性というべきであって、これに対して二元論というのは的を外した言い方であるように思います。おなじことが、デカルトの世界認識に対する評価に対しても言えるのではないか、これが本稿の中心をなす主張です。

しかし、この点に論を進める前に、ソフトウエアオブジェクトにつき、もう少し詳細にみておくことといたしましょう。

1.2. プログラマによるオブジェクトの取り扱い

計算機で何らかの処理を行う場合、さまざまなデータが扱われます。例えば、日付データなどは多くのプログラムで扱われます。ここで、あるプログラマが変数xを日付としてプログラム中で扱うというシチュエーションについてみてみましょう。

日付というクラス(オブジェクトの型)がDateとして定義されていれば、日付型変数xをプログラム中で扱うために、次のような宣言を行います。
      Date x;

クラス Date がどのように実装されているかをプログラマは知る必要はありません。それは、例えば年、月、日に対応する3つの整数として保持されているかもしれませんし、年と年初からの日数で保持されているかも知れませんし、あるいは特定の日付けからの経過日数で保持されているかもしれません。

必要なことは、クラス Date に対してプログラマが行う必要のある操作がきちんと定義されており、それをプログラマが理解していることです。 この操作として、例えば次のようなものがあるでしょう。

 (1) 3つの整数、年、月、日からDate型のオブジェクトを作る操作。
 (2) Date型のオブジェクトから、年、月、日に対応する整数を取り出す操作。
 (3) 二つのDate型オブジェクトの大小関係、等しいか等しくないかを判定する操作。
 (4) 二つのDate型オブジェクトの間の日数を求める操作。
 (5) Date型オブジェクトからある日数を経過した日をDate型オブジェクトとして求める操作。
 (6)Date型オブジェクトをプリントする操作。

これらは、わかりやすい形で定義することが肝要です。C++の場合、(1)は、クラスと同じ名前の関数(コンストラクタ)として定義されます。つまり、"x = new Date(yyyy, mm, dd)" とか、"x = new Date("yyyy/mm/dd")" などと書くことでDate型のオブジェクトxが作られるように定義しておきます。ここで、yyyyは年、mmは月、ddは日です。(2)は関数として定義され、例えばxから年を取り出す場合は "x.Year()" とすれば年に対応する整数が求まるようにします。(3)、(4)、(5)は比較演算子と加減算を定義するのが妥当でしょう。(6)は "x.Print()" などでxの内容がプリントされるようにします。

こうしてプログラマは、Date型の変数xを扱ってプログラムを書くわけですが、その際に必要となる知識は、Date型の変数に対してどのような操作が可能で、それはどのように記述すればよいのか、ということだけで、xがどのような形で計算機に格納されるかということまでは、プログラマは気にする必要はありません。

もちろん、あるプログラマは、クラス定義を新たに行うかもしれません。例にあげたクラス "Date" にしたところで、誰かがクラス定義を書き下しているから使えるわけです。そして、Dateのクラス定義を行う際には、そのデータ構造、すなわち、Date型のデータはどのように計算機に保持されるのか、という点に関しても考える必要があります。
 

1.3. 計算機におけるオブジェクトの実在

プログラムが計算機にロードされると、Date 型のオブジェクト x は、記憶装置内部の特定の領域を占有すると書きました。これは初期の計算機では正しかったのですが、今日の計算機ではもう少し複雑です。

主記憶の一部は、高速アクセスの可能なキャッシュ領域にいったん転送されます。また、主記憶領域が不足する場合は、主記憶にあるべきデータの一部はハードディスク上の仮想記憶に置かれます。

しかし、どのデータをキャッシュに置き、どのデータをハードディスク領域に置くかは、データのアクセス速度の効率化を目指して機械的に行われ、効率性以外の点では、オブジェクトは巨大な主記憶領域の特定のアドレス範囲を占有しているという事実に何の変わりもありません。

さて、実在、という観点からオブジェクトを考察してみましょう。

計算機は実在しますし、計算機のケースを開けてボードを眺めれば、記憶装置、すなわちランダムアクセスメモリ(RAM)のLSIも確認できます。技術資料や解説書を理解した人なら、RAMの内部に多数の記憶領域が存在することも了解できるでしょう。

このことから「記憶装置における領域」としてオブジェクトは、たしかに実在します。一方、「内部構造をもつデータとしてのオブジェクト」は実在するのでしょうか。

たしかにソースファイルは実在します。たとえば、ソースファイルを印刷すれば、ソースリストという形をもったものとして、オブジェクトの定義が書かれたプログラムが眼前に存在することが確認できます。

しかし、ソースリストが物理的に実在しているといえるのは、セルロースの薄片に付着したインクとしての実在であり、内部構造をもつデータとしてのオブジェクトが実在しているわけではありません。内部構造をもつデータとしてオブジェクトは、それを考え、あるいは読んで理解する人の精神的働きによってはじめて存在するのです。このような存在を概念的存在と呼びます。

人が何かを考える際のその内容は、人の頭の中にのみ存在する観念的存在ですが、その際、脳の内部に何らかの物理的痕跡を残しているはずです。しかし、これらの精神的活動が物理現象に結びついているとしても、精神的活動の中心的課題は、そうした行為を行っている際のニューラルネットワークにおける物理現象ではなく、精神的活動の扱う意味内容にあります。

本やメモ、あるいはニューラルネット内部で生じている現象は、それ自体、物理的な実在ではあるのですが、それらの存在が人に与える意味は、その物理的実在にあるのではなく、そこに書かれた内容であって、書き手あるいは読者の精神活動に資する効果に意味があります。すなわち、本やメモは、物理的な実在としてよりは、観念的な効果として我々の前にあるわけです。

オブジェクト指向プログラミングにおけるオブジェクトの二つの定義は、記憶装置の領域という物理的実在としてのオブジェクトと、プログラムを理解しようとする人間のもつ概念としてのオブジェクトに対応しています。

結局のところ、物理的実在としてのオブジェクトは、記憶装置の一定の領域として存在し、構造をもつデータとしてのオブジェクトは、プログラムを作成し、読解する人の概念です。オブジェクト指向プログラミングにおけるオブジェクトに対する考察がもたらした結論の興味深い点は、これがデカルトの「延長(ひろがり)」と「観念」という二元的見方によく対応していることに加え、そこには何の神秘性もないこと、オブジェクトを考える立場の相違がもたらすオブジェクトの二面性であるにすぎない、という点です。 

なお、計算機、記憶装置、領域なども人の概念なのですが、これらは「この世界に物理的に実在するものはエネルギー粒子の空間分布だけである」というときのエネルギー粒子なり空間なりの概念と同様のレベルにある概念です。

1.4. クラス(型)という概念

オブジェクト指向プログラミングについて、もう少しみていきましょう。

オブジェクトという概念は、特定の対象に対応する概念で、記憶装置の領域に対応します。

オブジェクトを指し示す一つの方法は、はオブジェクト固有の名前を用いるもので、世界認識における固有名詞に対応します。

オブジェクトを示すもうひとつの方法はポインタによるもので、計算機の実装上はオブジェクトを格納するアドレスを用いてオブジェクトを操作する方法です。複数の同種オブジェクトを含む配列も、ポインタと同様に扱われます。

ポインタを用いて物理的実在を指し示すことも、人の精神的活動ではごく一般に行われています。その一つの典型は、他の物理的実在との関係によるもので、「太郎君のお母さん」とか、「机の上の本」などがこれにあたります。前者は人型のオブジェクトである太郎君がもつインスタンス(データ)の一つに「人型オブジェクトである母親へのポインタ」が含まれており、これをたどることで特定の人を指し示すことができます。配列型のオブジェクト指定も良く使われる方法で、右から三番目の人、
などという言い方は良くいたします。

オブジェクト指向プログラミングで最も重要な概念は「クラス(型)」という概念でしょう。人の世界認識においては、種類を示す概念がこれにあたります。例えば、人、机、本、りんごなどの一般概念です。

クラスには、インスタンス(データ)とメソッド(操作)が定義されており、人であれば住所、氏名、年齢、職業などの個人データがインスタンスに相当しますし、メソッドとしては、挨拶する、話しかけるなどなどの行為が人というクラスに付属します。

クラスの一部はクラスであってよく、パソコンというクラスには、パソコン本体、ディスプレー、キーボードなどのパソコンの構成要素となるクラスが含まれ、パソコン本体にはさまざまなボードやメモリーやCPUなどの構成要素が、これらもまたクラスとして含まれています。

インスタンスは、基本的にクラス(単純なデータ型を含む)であり、その末端は、非常に単純なクラス、例えば数などとなっています。

また、クラスは他のクラスを継承することができます。人というクラスは哺乳類というクラスを継承しており、哺乳類は動物というクラスを継承しています。更に元をたどると、個体、というクラスを継承しており、個体には大きさや位置などのインスタンスを含みます。

継承と包含関係を用いると、複雑なデータ構造を比較的簡潔に記述することが可能であり、これは、科学の方法論と非常に類似したアプローチとなっております。

1.5. ソフトウエアプログラミングと世界認識

オブジェクト指向プログラミングがオブジェクト(操作対象)を個々のクラスに属するものとして扱うことを基本とするのと同様に、人の世界認識においても、対象物なり状況なりを特定の種類ないしパターンとして認識することが基本と思われます。

このような認識のあり方は、人以外の動物、例えば猫でも行っているはずで、眼前の小物体を「ねずみ」という概念に妥当すると判断するからこれを捕まえる行動を起こしているはずです。そのとき、猫はねずみの特性を理解しており、それが油断をしているとすばやく逃げるものであることも理解しているし、どのような逃げ方をするかも知っているはずです。そして、ねずみは猫にとって食物であることもわかっているわけです。

世界をクラスに属するオブジェクトの集合体として把握することは、個々のクラスの特性を知識として集積することで、世界に対する理解を深め、新しい事態に対する対応を可能とする基本的なメカニズムなのでしょう。

この、人や動物の世界認識の基本的アプローチをソフトウエアの方法論に取り入れたことが、オブジェクト指向プログラミングというソフト開発手法が成功した理由であるのかもしれません。

1.6. マンガの正体

あるとき突然、世界に対する理解が深まる、これまで悩んでいたことが瞬時に解消する、という幸福な一瞬があります。仏教で言えば解脱、悟りを開く、ということでしょう。実は私もそういう経験をしたことがありまして、それは何と、マンガを読んで、なのですね。

かつて私にも、悩んでいた時期があったのですね。元々が理科系人間の私、自然科学の信奉者でして、すべては素粒子の相互作用である、ということを理解していたわけです。

しかし、そうなりますと、この私自身は一体なんであるのか。パブロフの犬なのだろうか、と悩むわけですね。実際問題、その当時、唯物論に立脚した国家であるソビエト連邦は健在だったわけでして、パブロフが幅を利かせるソビエトの人が何を考えているのか、さっぱりわからなかったわけです。

で、そんなときに出会いましたのが、あるマンガでして、これが面白かったのですね。まあ、現実逃避といいますか、面白いものにはとことん付き合う良い心がけと言いますか、理由はどうあれ、そのマンガを繰り返し、繰り返し、飽きもせずに読んでいたわけです。

最初のうちは、ストーリーを追う。まあ、時系列的に筋を追っているのですが、何度か読むうちに、物語り全体の構成がみえてまいります。登場人物の関係とか、位置づけ、といったものがみえてきます。

更にそのうちに見えてきますのは、漫画家のタッチ、といったものでして、人物を表現するときの筆遣いや、背景の処理が見えてきます。茂みを表現する葉っぱの描き方など、なるほど、と思えるわけですね。

で、最後にわかりましたことが、マンガというものは、実は、紙の上に乗っているインクである、という事実なのですね。

これは驚くべき発見でして、何しろそのマンガを私は気に入って、何日も読みふけっていたわけです。でもそこにあるものは、確かに、紙の上にインクが付着しているモノ。それ以上でもなければ以下でもない。

そこで悟りましたことは、確かに自然科学は真実を語っている。でも、それがすべてではない、ということです。何しろ、マンガにおける科学的な真実はセルロースの薄片の上にインクが付着したもの。でもその中に私が見出していたのは、豊かな物語だったのですね。

まず、デカルト流に言いますと、そこにあるものは拡張(広がり)としての物理的実在であるのですが、私達はそこに物語を見出す。それは、ひとり知性によって見出された物語であるわけです。

私の言葉でいえば、物理的に実在しているといえるのはエネルギー粒子の空間的配置なのですが、人の精神はそこに物語の概念を見出す、というわけです。

そうなりますと、ことは簡単です。インクのシミに過ぎないマンガに心を引かれ、熱中する。ならば、エネルギー粒子の広がりに過ぎない自分自身にも、もう少し、自信を持ったらよいのではないだろうか。少なくとも、自分の物語、少々、腰を据えて鑑賞したら良いのではないか、なんて考えも出てくるわけですね。

いずれにいたしましても、このお話で重要なポイントはただ一つ。マンガはインクのシミである。でもそこに、人は豊かな物語を見出す、ということです。この二つの見方、いずれも否定すべきものではありません。同じマンガ本に、人は、少なくとも、二通りの見方をしている。これだけは確かな事実である、という点です。

オブジェクト指向プログラミングにおけるオブジェクトの二通りの定義も、マンガに対する二つの見方に対応しています。しかも、マンガに対する二つの見方が私の個人的経験に立脚しているのに対し、オブジェクト指向プログラミングの定義は書籍として出版されており、広く一般に認められているものと考えられます。

本稿のこの一章は、このような考えから、オブジェクト指向プログラミングにおけるオブジェクトについて、考察を行ったものです。物理的広がりと、人の知性がそこに見出す概念との二つのものの見方は、ソフトウエアにおけるオブジェクトにとどまらず、マンガにも、書籍にも、更には人の脳に対しても、同様な扱いができるのではないか、と考えている次第です。これらにつきましては、この先で、じっくりと検討することにしたいと考えております。