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

出典: フリー百科事典『ウィキペディア(Wikipedia)』

出典: フリー百科事典『ウィキペディア(Wikipedia)』
検索に移動

オブジェクト指向プログラミング(オブジェクトしこうプログラミング、: object-oriented programming、略語:OOP)とはプログラミング技法の一つであり、任意の関連性を持つデータ変数またはプロパティ)とコード関数またはメソッド)をひとつにまとめてオブジェクトとし、それぞれ異なる性質と役割を持たせたオブジェクトの様々な定義と、それらオブジェクトを相互に作用させる様々なプロセスの設定を通して、コンピュータプログラムを構築することを主眼にしている。

オブジェクト指向という用語自体は、計算機科学者アラン・ケイによって生み出されている。「Simula」言語などにインスパイアされたケイが1967年頃に口にしたと伝えられるこの造語は[1]、彼が1972年から開発を始めた言語「Smalltalk」の設計を説明する過程で明確な用語として発信され、1981年頃から知名度を得るようになった。しかしオブジェクト指向の要点としてケイが示したメッセージングの考え方はさほど認知される事はなく、代わりにクラスインスタンスの仕組みを注目させるだけに留まっている。同時にケイの手から離れたオブジェクト指向[疑問点]抽象データ型を中心にした解釈へと推移していき、1983年に計算機科学者ビャーネ・ストロヴストルップが公開した「C++」が好評を博したことで、オブジェクト指向に対する世間の理解は「C++」とそのモデルの「Simula 67」のスタイルで定着した。それに基づいてカプセル化継承ポリモーフィズムといった考え方も後年に確立された。

特徴[編集]

OOPには千差万別の見解が存在しており、その定義も未だ一律でないままにされているのが現状であるが、一般的にはクラスベースと呼ばれるスタイルが標準にされており、入門書もそれに準拠していることが多い。クラスベースの言語は静的型付け動的型付けの分類で大別されている。前者の例としては「C++」「Java」「C#」などが、後者では「Python」「ECMAScript」「Ruby」などが挙げられる。また、メッセージ式重視、多重ディスパッチ重視、関数型との融合、OOP的な純粋性の追求、非OOP言語のOOP拡張版といったポリシー上の分類も存在する。クラスベースは後述の抽象データ型Simula67由来の継承と動的ディスパッチを合わせたモジュール機能を土台にしたプログラミングスタイルであり、その名の通りクラスインスタンスの仕組みを中心にしている。それに対してクラス(型)とインスタンス(型付け値)の区別を意図的に無くしたプロトタイプベースOOP(JavaScriptなど)というスタイルもあるがマイノリティに留まっている。本節でもクラスベースOOPを基準にして説明する。

クラスとインスタンス[編集]

OOPの要点になるクラスは、データ構造とそれを扱うための操作・振る舞いをひとまとめにした一種のモジュール機能として定義されていることが多い。非OOP言語におけるプログラムモジュール(サブルーチンとデータの構成体)との相違点を挙げると、クラスにはモジュールの抽象化(abstraction)を促進させるカプセル化継承ポリモーフィズムといった概念に基づく言語機能が導入されており、プログラムの再利用性と保守性を高める上でより有用になっている。クラスのデータ構造はレコードないし構造体に似た書式で定義されることが多く、データ構造の要素は言語ごとにフィールドプロパティ属性、メンバ変数などと呼ばれている。クラスに定義される操作・振る舞いはメソッドやメンバ関数などと呼ばれる。

クラスベースではプログラム内のデータ要素を型理論に沿った(type)と型付け値(term)に分けて扱っている。その型の一種であるユーザー定義型(user defined type)がいわゆるクラスにされており、その型付け値がインスタンスと定義されている。ユーザー定義型とはいわゆる構造体に類似のものであり、OOPでは手続き(のポインタ)もそのメンバ要素にされている。クラスはデータとメソッドの構成を定義した「型」であり、それを計算対象や代入対象として用いれる「値」として実体化したものがインスタンスである。[独自研究?]クラスはインスタンスのひな型であり、インスタンスはクラスを実体化したものである。実体化とは対象クラスの全変数内容を決定し、ヒープ領域の基底アドレス(this)を定めた上でそこにメモリ展開するという作業を指している。コンパイル時にその構成が確定されるユーザー定義型は静的型付けであり、実行時にもその構成を変更できるユーザー定義型は動的型付けと呼ばれる。

オブジェクトとは[編集]

OOP言語仕様としてのオブジェクトの定義は多くの言語で曖昧化されているのが現状であり、これにはOOPの成立過程が関係している。OOPの原点であるSmalltalkは、クラスもまたメタクラスという型(クラス)の型付け値(インスタンス)であると定義しており、メタクラスもそのまたメタクラスという型の型付け値であるとしていたので、その相互再帰の連鎖をなしている型と型付け値の総称としてオブジェクトが用いられた。これが後のOOP言語では簡素化されて、型と型付け値はクラスとインスタンスの二者関係に固定され、メタクラスはクラス構成の動的変更機能に固定されたので、クラス(型)とインスタンス(型付け値)の相互再帰概念が失われたクラスベースでは、オブジェクトはインスタンスを漠然と指す言葉として残ることになった。

Smalltalk方言のSelfを原点とするプロトタイプベースは、この型と型付け値の区別を意図的に無くしたスタイルであり、この特徴によってクラスベースと明確に区別されている。数値・文字列・シンボル・配列・関数・構造体といった基本的な型は備えられているが、これはオブジェクト種類の区別に特化されたものなので、型理論に沿ったクラスベースのそれとは厳密には異なっている。クラス(型)とインスタンス(型付け値)の概念が無いプロトタイプベースでは、オブジェクトはあらゆるプログラム要素を指す総称用語としての意味をなしている。オブジェクトの構築はスロット(二項データ構築子)の再帰集合によってなされ、オブジェクトの識別はダックタイピングによってなされる。クラス概念が無いのでサブクラス化(継承)とインスタンス化の機能は成立せず、代わりにクローン(複製)によってオブジェクトの派生と実値化がなされている。

オブジェクト指向の三大要素[編集]

クラスベースOOPは上述のクラス機能を中心にしており、クラス機能の実装様式を規定している以下の三項目は、日本では三大要素または三大原則などと呼ばれている。非OOP言語のプログラムモジュールに三大要素仕様を加えたものがOOP言語のクラスになるが、各要素の軽視重視と導入方式には言語ごとに様々な違いがある。カプセル化はthis参照の機構とデータ/メソッドの可視性を指定できる機能、継承は自身のスーパークラスを指定できる機能、ポリモーフィズムはオーバーライド仮想関数テーブルを処理できる機能とされていることが多い。[独自研究?]

カプセル化[編集]

データ構造とそれを扱うためのメソッド群を情報隠蔽の概念と合わせてモジュール化するという手法がカプセル化と呼ばれる。カプセル化されたメソッドは、this値が暗黙の先頭引数として常に渡されるように実装される。this値とはクラスのデータ構造をメモリ展開するためのヒープ領域の基底アドレスを指しており、インスタンス化時に確定されたthis値によってメソッドは専用のデータ構造にアクセスできる。専用メソッドを通してのデータ構造の閲覧と変更は、抽象データ型の考え方に沿ったデータ構造の抽象化を意味することになり、これはデータ抽象英語版と呼ばれる。データ閲覧用メソッドはゲッター/アクセッサと呼ばれ、データ変更用メソッドはセッター/ミューテイタと呼ばれる。

情報隠蔽英語版はカプセル化されたデータ構造の各要素および各メソッドを、それぞれ外部公開と内部隠蔽に区分けする機能である。内部隠蔽されたデータ要素とメソッドはそのクラス外からのアクセスが禁止される。抽象データ型本来の形式ではデータ構造のみが隠蔽対象になるので、これはデータ隠蔽とも呼ばれる。データ要素とメソッドの外部公開範囲を指定する機能はアクセスコントロールと呼ばれており、クラスのレキシカルスコープを基準にした段階的なアクセス許可範囲は可視性と呼ばれる。可視性は無制限・任意クラスグループ限定・派生クラスグループ限定・自クラス限定の四段階がUMLでは標準にされている。

継承[編集]

既存クラスのデータ/メソッド構成に、任意のデータ/メソッド構成を付け足して、既存構成+新規構成の新しいクラスを定義するという手法が継承と呼ばれる。また、各クラスの共通構成部分を括りだして特有構成部分と分離することでオブジェクトを体系化し、加えて重複記述の削減をもたらす機能と解釈されることもある。これは差分プログラミング目的の継承と言われるが、2000年代になるとSOLID原則の重視に伴なって、既存構成に抽象メソッドを置いて新規構成にその実体メソッドを置くというメソッドのオーバーライド目的の継承の方が要点にされるようになっている。データ/メソッドの新規構成ではなく、メソッドの実装内容を付け足していくための継承である。そこでは特にデータ構造を付け足しての階層的なデータの分散配置は倦厭されるようになっている。

既存クラスは基底クラス、親クラス、スーパークラスなどと呼ばれ、新しいクラスは派生クラス、子クラス、サブクラスなどと呼ばれる。継承できるクラスが一つに限られている単一継承を採用している言語と、継承できるクラスの数に制限がない多重継承を採用している言語がある。抽象メソッドを持つクラスは抽象クラスと呼ばれる。抽象メソッドのみで構成される純粋抽象クラスの継承は、インターフェースの実装(継承)などと呼ばれて抽象化目的の継承になる。返り値の型と引数リストのみが定義されて実行コードブロックが未定義のままの抽象メソッドは、派生クラス側の実体メソッドでオーバーライドされる。

ポリモーフィズム[編集]

異なる種類のクラスに共通の操作インターフェースを持たせてオブジェクトの振る舞いを抽象化するという手法がポリモーフィズム(多態性)と呼ばれる。OOPで語られる多態性は多くの場合、継承構造を利用したサブタイプ多相を対象にしている。設計としてはコンパイル時に確定されたメソッド名から呼び出されるプロセス内容が実行時に決定されるという仕組みを指しており、一つのメソッド名からその実行時状態に合わせた個別のメソッド処理が呼び出されるようにするという演繹的意味と、各クラスの同種機能メソッドを一つの共通メソッドにまとめて実行時状態に合わせたメソッド処理が呼び出されるようにするという帰納的意味がある。

その実装としてはオーバーライド機能を活用した仮想関数と、実行時型チェックによる動的パターンマッチング機能を活用した総称関数の二つが挙げられる。前者は標準的なクラスベース向けであり、後者は関数型スタイル向けである。仮想関数英語版はスーパークラスの抽象メソッドの呼び出しを、それをオーバーライドしたサブクラスの実体メソッドの呼び出しにつなげるという機能である。総称関数英語版はオブジェクトの実行時パターンマッチングを用いた多重ディスパッチの独立関数であり、その引数にされた各オブジェクトの型(=クラス)の組み合わせによって実行コードブロックを選択決定するという機能である。

コンポジションとデリゲーション[編集]

コンポジション(合成)とデリゲーション(委譲)は継承を帰納的に分解した仕組みと言えるものであり、または合成と委譲による連携を演繹的に最適化した仕組みが継承であるとも言える。OOPにおける合成と委譲は、SmalltalkSimula67由来の継承機能をオブジェクトの再帰構成という観点から再解釈したものがデザイン上のルーツになっている。継承はIs-aの委譲、合成はHas-aの委譲と読み替えることができる。

合成とは、クラスに特定処理の委譲先になる部品クラスを1個以上持たせた構造であり、クラスがとある処理を要求されてそれに対応できるデータ/メソッドを持っていない場合は、それに対応できる部品クラスを選択して処理を委譲するという仕組みである。その要求判別と選択過程を自動化したものが継承であり、部品クラスを基底クラスに置き換えて暗黙の委譲先にしたものである。継承がもたらすデータ/メソッド検索の自動化は特にコーディング負荷を軽減した。しかしその暗黙委譲は実際に参照されるデータ/メソッドの把握を困難にし、リスコフの置換原則違反を招きやすいという欠点も明らかになったので、合成との使い分けが重視されるようになった。SOLID原則の重視に伴ない、既存構成に新規構成を付け足していくという差分プログラミング目的および共通構成を括りだして特有構成と分離していくという同様の目的では、継承よりも合成を用いる方がよいと考えられている。

動的ディスパッチとメッセージパッシング[編集]

動的ディスパッチはポリモーフィズムの原型的仕組みであり、継承構造上でのthis参照によるシングルディスパッチを最適化した機能が仮想関数である。動的ディスパッチはコンパイル時に確定されたメソッド名から呼び出されるメソッド内容が実行時に決定される仕組み全般を指す用語であり、メソッド名を基軸にして各引数の型によってメソッド内容が選択分岐される仕組みを意味するシングルディスパッチと多重ディスパッチを包括している。先頭引数の型パターンマッチング固定でメソッド内容が選択されるのはシングルになり、そうでないならば多重になる。

メッセージパッシングでは、引数の型に加えてメソッド名も実行時に解釈される要素にされており、そこでただのシンボルになったメソッドはセレクタと定義されている。セレクタはメッセージ式を基本文とするOOPで用いられる。object selector: paramような書式でオブジェクトの共通窓口となるメッセージレシーバーに、セレクタと引数値で構成されたメッセージが送られる。また、object.call(method_name, param)のような書式でオブジェクトの共通窓口関数をコールするのもメッセージパッシングと呼ばれる。これは遠隔手続きコールオブジェクト要求ブローカーで用いられており分散オブジェクトの標準的なインターフェース機構になっている。メソッド名(関数名)も実行時に解釈されるという特徴を指してメッセージパッシングと呼ぶ。メッセージレシーバー内では、渡されたセレクタの文字列照合による条件分岐によって実行コードブロックが選択されることが多く、OOP原点のSmalltalkはその実行コードブロックをメソッドと呼んでいた。

インターフェース[編集]

インターフェースはカプセル化を更に突き詰めた仕組みであり、データ抽象とメソッド抽象と情報隠蔽を合わせて実現する最もOOPらしい機能と言える[独自研究?]。OOPで言われるインターフェースとは、抽象メソッド主体で構成されている一種の抽象型と定義されており、主にソフトウェアコンポーネント間の相互通信媒体として用いられるものである。各言語での導入様式としては、抽象メソッドのみで構成された純粋抽象クラスが基本形にされている。インターフェースの抽象メソッドの実行コードブロックは、それを実装したクラスの同名メソッドで記述されることになる。インターフェースはクラスの振る舞いを投影した抽象体と言えるものである。ゲッター、セッター、プロセスになる各抽象メソッドの実装内容は利用者側から隠されて実行時のその都度に決定される。

多重ディスパッチとミックスインとトレイト[編集]

多重ディスパッチは振る舞い(behavior)を中心にしてオブジェクトを扱うための手法であり、これを重視したOOPでのオブジェクトは、振る舞いサブタイピングが省かれたデータクラスに特化されることになる。多重ディスパッチは一つのメソッド名を基軸にして、その引数になった各インスタンスの型(=クラス)の組み合わせに従い、その実行コードブロックが選択決定(ディスパッチ)されるという仕組みである。その選択分岐にはインスタンスのパターンマッチングが用いられ、インスタンスの型だけでなく、型に付加された文脈(コンテキスト)による判別の方が重視されている。この文脈はマーカーインターフェースによるアドホック多相と同義である。クラスに基底クラス(データクラス)と1個以上の文脈(振る舞い)を合わせて多重継承させるというサブタイプ多相とアドホック多相の融合スタイルがミックスインと呼ばれる。クラスにはただのマーキングとしての文脈が継承され、その文脈に結び付けられているメソッド内容は、クラス外部で独立して定義されるという点が特徴である。

多重ディスパッチは関数型プログラミング寄りのポリモーフィズム様式と言えるものであり、そこでは多重ディスパッチ用の独立関数がメソッドと呼ばれる。正確にはディスパッチ先になる個々の実行コードブロックがメソッドであり、その多重定義で総称メソッド(総称関数)と呼ばれる。多重ディスパッチの流れを汲むトレイトは振る舞いを主体にした継承機構であり、サブタイプ多相のインターフェースに対して、概念上はアドホック多相を仲介にしてデータクラスとメソッドモジュールを結び付ける仕組みである。インターフェースがデータクラスを軸にしてそのメンバであるメソッドの多態性を扱う仕組みであるのに対し、トレイトはメソッドを軸にしてその暗黙引数にされたデータクラスの多態性を扱う仕組みである。インターフェースではメソッド定義限定でその継承クラス内でメソッド実装がなされるのに対し、トレイトではメソッド定義と実装の双方をその継承クラスから独立して行なうのが特徴である。またインターフェースは記名的型付けでその継承の有無が判別されるのに対し、トレイトは構造的型付けで判別されることが多い。トレイトは関数型プログラミング寄りの継承様式と言えるものである。

歴史[編集]

1954年に初の高水準言語FORTRANが登場すると、開発効率の劇的な向上と共にソフトウェア要求度も自然と高まりを見せてプログラム規模の急速な拡大が始まった。それに対応するために肥大化したメインルーチンをサブルーチンに分割する手法と、スパゲティ化したgoto命令制御フロー構文に置き換える手法が編み出され、これらは1960年に公開された言語「ALGOL60」で形式化された。当時のALGOLはアルゴリズム記述の一つの模範形と見なされたが、それと並行して北欧を中心にした計算機科学者たちはより大局的な観点によるプログラム開発技法の研究を進めていた。

Simulaの開発(1962 - 72)[編集]

1962年、ノルウェー計算センターでモンテカルロ法シミュレーションを運用していた計算機科学者クリステン・ニゴールは、ALGOL60を土台にしてProcessと呼ばれるコルーチン機構を加えたプログラミング言語「Simula」を公開し、続けてその拡張にも取り組んだ。ニゴールの同僚で、1963年にSimulaを汎用機UNIVAC系統上で運用できるように実装した計算機科学者オルヨハン・ダールは、Processにローカル変数構造を共有する手続き(サブルーチン)を加えてパッケージ化する言語仕様を考案し、これは一定の変数と手続きをまとめるモジュールと同類の機能になった。程なくしてALGOL60コンパイラに準拠していての限界を悟ったニゴールとダールは、1965年からSimulaを一から再設計するように方針転換した。その過程で彼らは、計算機科学者アントニー・ホーアが考案して1962年のSIMSCRIPT(FORTRAN用のスクリプト)に実装していたRecord Classを参考にしている。Record Classはソースコード水準の抽象表現を、各汎用機に準拠したマシンコード水準の実装符号に落とし込む段階的データ構造のプログラム概念であった。これをモデルにした継承と、その継承構造を利用した仮想手続き(仮想関数)の仕組みも考案され、上述のパッケージ化されたProcess(モジュール)に継承と仮想手続きの両機能を加えたものを「クラス」と定義し、クラスをメモリに展開したものを「オブジェクト」と定義する言語仕様がまとまり、1967年に「Simula67」が初公開された。オブジェクトという用語は、MITの計算機科学者アイバン・サザランドが1963年に開発したSketchpadCADGUIの元祖)の設計内にあるObjectが先例であった。Simula67コンパイラはまずUNIVAC上で運用され、翌年から汎用機バロースB5500などでも稼働されて北欧、ドイツ、ソ連の各研究機関へと広まり、1972年にはIBM汎用機System/360などにも導入されて北米全土にも広まった。その主な用途は離散事象および物理シミュレーションであった。

構造化プログラミングの提唱(1969 - 75)[編集]

Simulaの普及と前後して1960年代半ばになると、プログラム規模の際限なき拡大に伴う開発現場の負担増大が顕著になり、いわゆるソフトウェア危機問題が計算機科学分野全般で取り沙汰されるようになった。その解決に取り組んだ計算機科学者エドガー・ダイクストラは、1969年のNATOソフトウェア工学会議で「構造化プログラミング」という論文を発表しトップダウン設計、段階的な抽象化、階層的なモジュール化、共同詳細化(抽象データ構造と抽象ステートメントのjoint)といった開発効率向上のための技法を提唱した。しかしこの構造化プログラミングは後に曲解されて制御フロー構文(順次・分岐・反復)を中心にした解釈の方で世間に広まることになり、ダイクストラ本来の主旨であったプログラムモジュールを抽象体として扱おうとする内容は忘却されている。共同詳細化は抽象データ構造を専用ステートメントを通して扱うという概念である。これはSimulaの手続きを通してクラス内の変数にアクセスするという仕組みをモチーフにしていた。段階的な抽象化と階層的なモジュール化は時系列的にも、SIMSCRIPTの段階的データ構造と、Simura67の継承による階層的クラス構造を模倣したものであった。ダイクストラホーアダールの三名は1972年に『構造化プログラミング』と題した共著を上梓していることから互いの研鑽関係が証明されている。その階層的プログラム構造という章の中でダールは、Simulaの目指した設計を更に明らかにした。

1974年にMITの計算機科学者バーバラ・リスコフは「抽象データ型」というプログラム概念を提唱し、ダイクストラが提示したモジュールの共同詳細化を、その振る舞いによって意味内容が定義される抽象データという考え方でより明解に形式化した。一方、1970年にPascalを開発していた計算機科学者ニクラウス・ヴィルトは、1975年にModulaを提示してモジュラープログラミングというパラダイムを明確にしている。また、1974年頃からIBM社中心の研究者たちが、サブルーチンとデータの構成体としてのプログラムモジュールを扱う構造化設計および構造化分析と総称される技法を発表し、この構造化開発はオブジェクト指向普及前の80年代末までのソフトウェア開発の主流になっている。このようにいささか奇妙ではあるが、Simulaのクラスとオブジェクトというプログラム概念は、プログラムモジュールの考案から構造化分析設計技法へといった進化の流れとは関係なく、しかもその前段階において生まれていた。

Smalltalkとオブジェクト指向の誕生(1972 - 81)[編集]

Simula発のProcessとクラスの示した可能性は、パロアルト研究所の計算機科学者アラン・ケイによる「メッセージング」という考え方のヒントになった。ケイはプログラム内のあらゆる要素をオブジェクトとして扱い、オブジェクトはメッセージの送受信でコミュニケーションするという独特のプログラム理論を提唱した。それには従来の関数呼び出しをセレクタの実行時解釈に置き換えて積極的な委譲を推進するメッセージ式と、プログラムコードとしても解釈できるデータ列を送信してそれを任意のタイミングで評価(eval)することで新たなデータを導出できるなどのアイディアが盛り込まれていた。これらの遅延結合パラダイムは非同期通信や単方向通信への可能性をも開いており、この発想の背景にはLISPの影響があった。メッセージを駆使するオブジェクトの構築には、Simula発のそれにプラトンイデア論を重ね合わせたクラスインスタンスの仕組みが導入された。オブジェクトとメッセージングの構想に基づいて開発された「Smalltalk」はプログラミング言語とGUIフレームワークを併せたものとなり、1972年にデータゼネラルNova上での1000行程度のBASICを使った試作(概念実証)を経て、翌1973年に新開発されたゼロックスAlto上で本格稼働された。Smalltalkの設計を説明するためにケイが考案した「オブジェクト指向」という用語はここで初めて発信された。またケイのメッセージング構想はMITの計算機科学者カール・ヒューイットに能動的なプロセス代数を意識させて[2]、1973年発表のアクターモデルのヒントにもなっている。しかし委譲の多用とデータ列が常にコード候補としても扱われる処理系は、当時のコンピュータには負荷が大きく実用的な速度を得られないという問題にすぐ直面した。Smalltalk-74(新たに開発されたBitBLTを使った高速描画版Smalltalk-72)からSmalltalk-76の過程で、やむなくメッセージは(多くの場合)関数の動的コールに、メソッドはパターンマッチ処理から単なる関数へ置き換えられるなど構想時の柔軟さが失われるほど最適化された。また、ケイの留保した継承機構[3]も導入されてオブジェクトは抽象データ型の性格も有するようになった。

1980年のSmalltalk-80は、元々はメッセージを重視していたケイを自嘲させるほど同期的で双方向的で手続き的なオブジェクト指向へと変貌していた。それでも動的ディスパッチと委譲でオブジェクトを連携させるスタイルは画期的であり、1994年に発表されるデザインパターンの模範にもされている。1981年に当時の著名なマイコン専門誌『BYTE』がSmalltalkとケイ提唱のオブジェクト指向を紹介して世間の注目を集める契機になったが、ケイの思惑に反して技術的関心を集めたのはクラス機構の方であった。オブジェクト指向は知名度を得るのと同時に、Simula発のクラスとそれを理論面から形式化した抽象データ型を中心に解釈されるようになり、それらの考案者がケイの構想とは無関係であったことから、オブジェクト指向の定義はケイの手を離れて独り歩きするようになった。

C++の開発と普及(1979 - 88)[編集]

Simulaを研究対象にしていたAT&Tベル研究所の計算機科学者ビャーネ・ストロヴストルップは、1979年からクラス付きC言語の開発に取り組み、1983年に「C++」を公開した。C++で実装されたクラスは、Simula譲りの継承と仮想関数に加えて、レキシカルスコープの概念をクラス構造に応用したアクセスコントロールを備えていた。C++で確立されたアクセスコントロールはカプセル化の元になったがコードスタイル上ほとんどザル化されており、その理由からストロヴストルップ自身もC++は正しくない(not just)オブジェクト指向言語であると明言している。1986年にソフトウェア技術者バートランド・メイヤーが開発した「Eiffel」の方は、正しいオブジェクト指向を標榜してクラスのデータ抽象を遵守させるコードスタイルが導入されていた。クラスメンバ(フィーチャー)は属性、手続き、関数の三種構成で、手続きで属性を変更し関数で属性を参照するという形式に限定されており、これは抽象データ型の振る舞い意味論に沿った実装であった。アクセスコントロールはモジュラープログラミングの情報隠蔽に沿った方式になり、仮想関数機能は延期手続き/関数として実装された。

1986年からACMオブジェクト指向会議(OOPSLA)を年度開催し、そのプログラミング言語セクションでは抽象データ型の流れを汲むクラス・パラダイムが主要テーマにされ、それを標準化するための数々のトピックが議題に上げられている。モジュール性、情報隠蔽、抽象化、再利用性、階層構造、複合構成、実行時多態、動的束縛総称型自動メモリ管理といったものがそうであり、参画した識者たちによる寄稿、出版、講演を通して世間にも広められた。そうした潮流の中でストロヴストルップはデータ抽象の重要性を訴え、リスコフ基底と派生に分けたデータ抽象の階層構造の連結関係について提言した。契約による設計を提唱するメイヤーが1988年に刊行した『オブジェクト指向ソフトウェア構築』は名著とされ、Eiffelを現行の模範形とする声も多く上がった。ただしこれは学術寄りの意見でもあったようで、世間のプログラマの間では厳格なEiffelよりも柔軟で融通の利くC++の人気の方が高まっていた。他方でオブジェクト指向本来の原点であるメッセージ・メタファに忠実であろうとする動きもあり、1984年に開発された「Objective-C」はSmalltalkをモデルにしてそれを平易化した言語であった。そのメッセージレシーバーは静的なメソッド機構優先の動的ディスパッチ機構という方式で実装された。メッセージレシーバの仕組みは遠隔手続き呼出し/オブジェクト要求ブローカーの実装に適していたので分散システムとオブジェクト指向の親和性を認識させることになった。

コンポーネントとネットワーク(1989 - 97)[編集]

ネットワーク技術の発展に連れて、データとメソッドの複合体であるオブジェクトの概念は、分散システム構築のための基礎要素としての適性を特に見出される事になり、IBM社Apple社サン社などが1989年に共同設立したOMGは、企業システムネットワーク向け分散オブジェクトプログラミング規格となるCORBAを1991年に発表した。その前年にマイクロソフト社ウェブアプリケーション向けの分散オブジェクトプログラミング技術となるOLEを発表し、1993年にはCOMと称するソフトウェアコンポーネント仕様へと整備した。このCOMの利用を眼目にしてリリースされた「Visual C++」「Visual Basic」はウェブ時代の新しいプログラミング様式を普及させる先駆になった。この頃に抽象データ型のメソッドを通したデータ抽象、データ隠蔽、アクセスコントロールおよび分散オブジェクトのインターフェース機構によるプログラムの抽象化といった概念は、カプセル化という用語にまとめられるようになった。クラスの継承が最もオブジェクト指向らしい機能と見なされていたのが当時の特徴であった。継承構造を利用した振る舞いサブタイピング及び動的ディスパッチは多態性という用語に包括された。こうしていわゆるオブジェクト指向の三大要素がやや漠然と確立されている。1996年にサン社がリリースした「Java」は三大要素が強く意識されたクラスベースであり、その中の分散オブジェクト技術はBeansと呼ばれた。類似の技術としてApple社もMacOS上でObjective-Cなどから扱えるCocoaを開発している。また、1994年から96年にかけて「Python」「Ruby」「JavaScript」といったオブジェクト指向スクリプト言語がリリースされ、従来の静的型付けに対する動的型付けと、クラスベースに対する新しいプロトタイプベースの認知度を高めている。

抽象化を旨とするオブジェクト指向ではそのプログラミング自体の抽象化も積極的に推進されている。80年代後半から立ち上げられたオブジェクト指向分析(OOA)やオブジェクト指向設計(OOD)の各手法から導き出されるコンセプトモデルを、多角的にチャート化ないしダイアグラム化するための数々のソフトウェア開発手法がOOPSLA界隈の識者たちから発表されるようになり、そこで用いられる形式言語オブジェクトモデリング言語英語版と呼ばれた。これはプログラミングのためのプロトタイプ(ひな型)として重視され、オブジェクト指向ではモデリング言語プログラミング言語が並んでソフトウェア開発の両輪になった。1994年にモデリング言語の代表的な活用例であるGOFデザインパターンが初回発表され、後のオブジェクト指向学習では非常に重視されるようになった。1995年にモデリング言語の標準化を企図したUMLがOOPSLAで初回発表され、1997年にOMGの標準モデリング言語にされている。

オブジェクト指向言語一覧[編集]

  • Simula67 1967年 静的
  • Smalltalk 1972年 動的・メッセージ式・純粋系
  • C++ 1983年 静的
  • Objective-C 1984年 静的と動的・メッセージ式
  • Object Pascal 1986年 静的
  • Eiffel 1986年 静的・純粋系
  • Self 1987年 動的・プロトタイプベース・メッセージ式・純粋系
  • Modula-3 1988年 静的
  • Common Lisp(CLOS) 1988年(ANSI規格化は1994年) 動的・多重ディスパッチ
  • Oberon-2 1991年 静的
  • Dylan 1992年 動的・関数型・多重ディスパッチ
  • Lua 1993年 動的・プロトタイプベース
  • Python 1994年(ver1.0) 動的
  • Delphi 1995年 静的
  • Ada 1995年からOOP化 静的
  • Perl 1995年からOOP化 動的
  • Ruby 1995年 動的・純粋系
  • Java 1996年(ver1.0) 静的
  • JavaScript 1996年(first released) 動的・プロトタイプベース
  • OCaml 1996年 静的・関数型
  • Squeak 1996年 動的・メッセージ式
  • ECMAScript 1997年 動的・プロトタイプベース
  • C# 2000年 静的と動的
  • Visual Basic.NET 2001年 静的
  • D言語 2001年 静的
  • Io 2002年 動的・プロトタイプベース・メッセージ式
  • COBOL 2002年からOOP化 静的
  • FORTRAN 2003年からOOP化 静的
  • R言語 2003年からOOP化 動的・関数型・多重ディスパッチ
  • Scala 2003年 静的・関数型
  • Groovy 2003年 動的
  • PHP 2004年からOOP化 静的と動的
  • F# 2005年 静的・関数型
  • MATLAB 2008年からOOP化 動的・関数型
  • Go 2009年 静的
  • Rust 2010年 静的・関数型
  • Kotlin 2011年 静的
  • Ceylon 2011年 静的
  • Dart 2011年 静的・関数型 
  • Elixir 2011年 動的・関数型
  • Julia 2012年 動的・関数型・多重ディスパッチ
  • TypeScript 2012年 静的と動的・関数型
  • Swift 2014年 静的・プロトコル指向
  • Raku 2015年 静的と動的

脚注[編集]

[脚注の使い方]
  1. ^ “At Utah sometime after Nov 66 when, influenced by Sketchpad, Simula, the design for the ARPAnet, the Burroughs B5000, and my background in Biology and Mathematics, I thought of an architecture for programming. It was probably in 1967 when someone asked me what I was doing, and I said: "It's object-oriented programming".”Alan Kay on the Meaning of “Object-Oriented Programming”
  2. ^ “Our research has concentrated on the development of a rigorous model of computation based on relationship among computational events. The development of this model has been greatly influenced by Seymour Papert's “little people” model of computation, a seminar given by Alan Key at M.I.T. on an early version of Smalltalk, and the work of Church, Fischer, Landin, on formalisms based on the lambda calculus.”Induction and Meta-evaluation
  3. ^ “I didn't like the way Simula I or Simula 67 did inheritance (though I thought Nygaard and Dahl were just tremendous thinkers and designers). So I decided to leave out inheritance as a built-in feature until I understood it better. ”Alan Kay on the Meaning of “Object-Oriented Programming”

関連項目[編集]