「オブジェクト指向プログラミング」の版間の差分
削除された内容 追加された内容
SpaceMeteor (会話 | 投稿記録) Apple改名に伴う変更 |
|||
(同じ利用者による、間の20版が非表示) | |||
6行目:
{{Wikibooks|オブジェクト指向|オブジェクト指向}}
'''オブジェクト指向プログラミング'''(オブジェクトしこうプログラミング、{{Lang-en-short|''object-oriented programming''}}、略語:OOP)とは[[プログラミング]]技法の一つであり、
'''[[オブジェクト指向]]'''という
== 特徴 ==
{{独自研究|date=2021-04}}
OOPでは[[クラスベース]]と呼ばれるスタイルが標準にされている。他に[[プロトタイプベース]]と呼ばれる後発のスタイルもあるが、こちらは少数派である。クラスベースのOOP言語は、[[Smalltalk]]様式と[[C++]]様式で二分されており、C++の方がずっと多数派である。C++様式は、[[静的型付け]]と[[動的型付け]]の分類で大別されている。それらの主な特徴を箇条書きするとこうなる。
* [[クラスベース]] - クラスのインスタンス化でオブジェクトを構築する。
** [[Smalltalk]]様式 - クラスとインスタンスの[[相対性]]を付与してオブジェクトを体系化している。動的型付け中心。[[メッセージパッシング]]による多態性。
** [[C++]]様式 - クラス(型)とインスタンス(型付け値)に分離してオブジェクトを体系化している。{{仮リンク|動的ディスパッチ|en|Dynamic dispatch}}による多態性。
*** [[静的型付け]] - 実行時のクラス構成が基本的に固定されている。
*** [[動的型付け]] - 実行時のクラス構成の変更が前提にされている。
* [[プロトタイプベース]] - オブジェクトのクローンでオブジェクトを構築する。クラスとインスタンスの[[相対性]]をオブジェクトから撤廃して、プロトタイプでオブジェクトを体系化している。動的型付け中心。[[動的束縛|動的バインディング]]による多態性。
本稿では最も標準的なクラスベースのC++様式の静的型付けを基準にして説明する。
=== クラスとインスタンス ===
OOPの要点である[[クラス (コンピュータ)|クラス]]は、[[データ構造]]とそれを扱うための操作・振る舞いをひとまとめにした一種の[[モジュール|プログラムモジュール]]機能として定義されており、その実装は[[Simula|Simula67]]由来の[[継承 (プログラミング)|継承]]と動的ディスパッチを加えた[[抽象データ型]]のスーパーセットにされていることが多い。クラスのデータ構造は[[レコード型]]や[[構造体]]に似た書式で定義されることが多く、データ構造の要素は言語ごとに[[フィールド (計算機科学)|フィールド]]、[[プロパティ (プログラミング)|プロパティ]]、[[属性]]、メンバ変数などと呼ばれている。クラスに定義される操作・振る舞いは[[メソッド (計算機科学)|メソッド]]やメンバ[[関数 (プログラミング)|関数]]などと呼ばれる。メソッドとは、特定の対象に所属させることを前提にして[[This (プログラミング)|This参照]]を多相シンボルにしたディスパッチコードとしての[[関数 (プログラミング)|関数]]/[[手続き]]を意味している。
OOP言語の[[クラス (コンピュータ)|クラス]]と、そうでない言語での[[モジュール]]の違いを知ることは、OOPを理解する上でも重要になる。どちらも[[プロシージャ|手続き]]と[[データ]]の複合体であるが、クラスの第一の特徴はそれに[[継承 (プログラミング)|継承]]が備えられていることであり、次に[[This (プログラミング)|This参照]]の機構と、[[継承 (プログラミング)|継承]]構造上の内包的な{{仮リンク|動的ディスパッチ|en|Dynamic dispatch}}である。その次になる{{仮リンク|情報隠蔽|en|information hiding}}と、定義と実装に分離しての[[抽象化 (計算機科学)|抽象化]]の機構は、OOP以前の{{仮リンク|モジュラルプログラミング|en|Modular programming}}からのものである。振る舞い抽象を担っている[[インタフェース (抽象型)|インターフェース]]の概念もそちらが先例であったが、データ抽象を担っている[[カプセル化]](情報隠蔽とThis参照の融合)の採用はOOPが最初である。[[継承 (プログラミング)|継承]]構造上の内包的な動的ディスパッチによる[[派生型|サブタイピング]](=[[ポリモーフィズム]])はOOP発祥であるが、それを純粋化すると前述の[[インタフェース (抽象型)|インターフェース]]になる。OOP以前の[[構造化分析設計技法|構造化開発]]のモジュールには情報隠蔽はあるが、[[継承 (プログラミング)|継承]]はなく、[[This (プログラミング)|This参照]]・[[カプセル化]]・[[派生型|サブタイピング]]・[[インタフェース (抽象型)|インターフェース]]といった抽象化機構も持たない。なお、{{仮リンク|振る舞いサブタイピング|en|Behavioral subtyping}}は[[多重ディスパッチ]]中心OOPでは軽視されており、カプセル化は[[プロトタイプベース]]OOPでは軽視されている。従ってOOPを特徴付けている本来の要素とは即ち[[継承 (プログラミング)|継承]]であり、その真偽はともかくとして、継承はプログラムの再利用性と保守性を高めるためのメカニズムと定義されている。
C++様式のクラスベースは[[オブジェクト (プログラミング)|オブジェクト]]を、[[型理論]]に沿った[[型システム|型]](type)と[[型付け|型付け値]](term)に分離している。その型の一種であるユーザー定義型(user defined type)がクラスにされており、その型付け値が[[インスタンス]]になっている。ユーザー定義型とは[[構造体]]と同じものであり、OOPでは[[手続き]](のポインタ)も構造体メンバにされている。ユーザー定義型は[[オブジェクト型]]とも呼ばれるが、このオブジェクト型と後節の「[[オブジェクト (プログラミング)|オブジェクト]]」の意味上の繋がりはない。[[クラス (コンピュータ)|クラス]]はインスタンスのひな型であり、[[インスタンス]]はクラスを実体化したものである。実体化=インスタンス化とは対象クラスの全変数内容を決定し、[[ヒープ領域]]の基底アドレス([[This (プログラミング)|This]])を定めた上でそこにメモリ展開するという作業を指している。コンパイル時にその構成が確定されるユーザー定義型は[[静的型付け]]であり、実行時にもその構成を変更できるユーザー定義型は[[動的型付け]]である。
=== オブジェクトとは ===
[[クラスベース]]言語での「[[オブジェクト (プログラミング)|オブジェクト]]」は、一般的には[[インスタンス]]を指す用語として説明されているが、このような重複語になった背景にはOOPの原点である[[Smalltalk]]からの事情がある。Smalltalkは、全てのプログラム要素は[[オブジェクト (プログラミング)|オブジェクト]]であり、全てのオブジェクトはクラスのインスタンス化であり、クラスもまたオブジェクトであると定義していた。そこでは[[クラス (コンピュータ)|クラス]]もまた[[メタクラス]](型)の[[インスタンス]]化(型付け値)になり、そのメタクラスもまた他のメタクラスのインスタンス化になっていたので、[[クラス (コンピュータ)|クラス]]と[[インスタンス]]は即ちオブジェクトの性質([[相対性]])を指すための言葉になっていた。これが[[C++]]様式では簡素化されて、クラスとインスタンスは[[型システム|型]]と[[型付け|型付け値]]の役割に固定され、メタクラスはクラス構成の動的変更機能に固定されたので、上述のインスタンス化の[[相互再帰]]が失われたオブジェクトは、インスタンスと同じ意味の言葉として残されることになった。またSmalltalkは、オブジェクトは他のオブジェクトと相互作用(interaction)するとも定義しており、この相互作用とは各種演算と同義である。Smalltalkのクラスは型付け値でもあるのでオブジェクトであるが、C++様式のクラスはただの型なので演算対象に出来ないことからオブジェクトではなくなっている。
Smalltalk方言の[[Self]]を原点とする[[プロトタイプベース]]は、オブジェクトからクラスとインスタンスの[[相対性]]を無くしたスタイルである。数値・文字列・配列・関数・シンボル・[[構造体]]([[オブジェクト型]])といった[[プリミティブ型|基本的な型]]は備えられているが、これはオブジェクト種類の区別に特化されたものなので、[[型理論]]に沿ったクラスベースの[[型システム|それ]]とは厳密には異なっている。クラス性質を除去したオブジェクトは事実上のインスタンスに一元化されており、その全てが相互作用(interaction)する。オブジェクトの表現はスロット(シンボルとコンテンツのペアデータ)の[[可変長配列]]でなされており、オブジェクトの識別は専ら[[ダックタイピング]]によってなされる。クラス概念が無いのでサブクラス化とインスタンス化は成立せず、代わりにクローン(複製)によってオブジェクトの継承がなされており、クローンはインスタンス化の代替になる。複製元オブジェクトは、複製先オブジェクトのプロトタイプと呼ばれる。
=== オブジェクト指向の三大要素 ===
====
データ構造とそれを扱うためのメソッド群を情報隠蔽の概念と合わせてモジュール化(パッケージ化)するという手法が[[カプセル化]]と呼ばれる。カプセル化されたメソッドは、[[This (プログラミング)|This値]]が暗黙の先頭引数として常に渡されるように実装される。This値とはクラスのデータ構造をメモリ展開するための[[ヒープ領域]]の基底アドレスを指しており、インスタンス化時に確定されたThis値によってメソッドは専用のデータ構造にアクセスできる。専用メソッドを通してのデータ構造の閲覧と変更は、[[抽象データ型]]の考え方に沿ったデータ構造の抽象化を意味することになり、これは{{仮リンク|Data Abstraction|en|Abstraction (computer science)|label=データ抽象}}と呼ばれる。データ閲覧用メソッドはゲッター/アクセッサと呼ばれ、データ変更用メソッドはセッター/ミューテイタと呼ばれる。
{{仮リンク|情報隠蔽|en|information hiding}}とはそのクラスのデータ構造の各要素および各メソッドを必要に応じて内部隠蔽するという概念である。内部隠蔽されたデータ要素とメソッドはそのクラス外部からのアクセスが禁止される。[[抽象データ型]]本来の形式ではデータ構造のみが隠蔽対象になるので、これはデータ隠蔽とも呼ばれる。隠蔽指定外のデータ要素とメソッドは外部公開されて、そのクラス外部からもアクセス可能になる。外部公開の範囲を指定する機能は[[アクセスコントロール]]と呼ばれており、これが内部隠蔽の仕組みを担っている。クラスの[[レキシカルスコープ]]を基準にした段階的なアクセス許可範囲は可視性と呼ばれる。可視性は無制限・任意クラスグループ限定・派生クラスグループ限定・自クラス限定(内部隠蔽)の四段階が[[統一モデリング言語|UML]]では標準にされている。
==== [[継承 (プログラミング)|継承]] ====
既存クラスのデータ/メソッド構成に、任意のデータ/メソッド構成を付け足して、既存構成+新規構成の新しいクラスを定義するという手法が[[継承 (プログラミング)|継承]]と呼ばれる。また、各クラスの共通構成パートを括りだして特有構成パートと分離することでオブジェクトを分類体系化し、同時にその共通構成パートの記号化によってソースコード内の重複記述を削減する機能とも解釈される。これは差分プログラミング目的の継承であり、1990年代までは多用された。2000年代になると[[SOLID]]原則の重視に伴なって、既存構成に抽象メソッドを置いて新規構成にその実体メソッドを置くという[[オーバーライド|メソッドオーバーライド]]を用いるための{{仮リンク|振る舞いサブタイピング|en|Behavioral subtyping}}目的の継承が要点にされるようになっている。データ/メソッドの新規構成ではなく、メソッドの実装内容を付け足していくための継承である。そこでは特にデータ構造を付け足しての階層的なデータの分散配置は倦厭されている。
既存クラスはスーパークラス・親クラス・基底クラスなどと呼ばれ、新しいクラスはサブクラス・子クラス・派生クラスなどと呼ばれる。親と子は差分プログラミング重視で用いられ、基底と派生はサブタイピング重視で用いられる。継承できるクラスが一つに限られている単一継承を採用している言語と、継承できるクラスの数に制限がない多重継承を採用している言語がある。<!-- 概念的に インターフェース継承(型継承、[[is-a関係]]、下位分類)と 実装の継承 の2つの側面があるといったことを書いた方がよさそう。 記述によっては両方の継承関係が同時に生じる。 -->抽象メソッドを持つクラスは抽象クラスと呼ばれる。基底クラス側で返り値の型と引数リストのみが定義されて実行コードブロックが未定義のままの抽象メソッドは、その派生クラス側の実体メソッドで[[オーバーライド]]される。オーバーライドは遅延結合による多相な[[複雑系]][[アルゴリズム]]を表現するオープン[[再帰]](open recursion)のメカニズムにもなっている。
抽象メソッドのみで構成される純粋抽象クラスは[[インタフェース (抽象型)|インターフェース]]と呼ばれ、その継承は実装(implementaion)と呼ばれる。実装継承という俗称もある。実装はサブタイピングによる[[Is-a]]関係を完全順守させるためのメカニズムであり、継承とは別個の概念として扱われている。{{仮リンク|モジュラルプログラミング|en|Modular programming}}が先例になる実装は、[[継承 (プログラミング)|継承]]から[[派生型|派生]](subtyping)への先祖返りと言えるものである。
====
異なる種類のクラスに共通の操作インターフェースを持たせてオブジェクトの振る舞いを抽象化するという手法が[[ポリモーフィズム]](多態性)と呼ばれる。OOPで語られる多態性はもっぱら継承構造を利用した{{仮リンク|サブタイプ多相|en|Subtyping}}を対象にしているが、{{仮リンク|アドホック多相|en|Ad hoc polymorphism}}もサポート的に用いられており、{{仮リンク|パラメトリック多相|en|Parametric polymorphism}}はコンポジションで用いられている。そのサブタイプ多相の設計としてはコンパイル時に確定されたメソッド名から呼び出されるプロセス内容が実行時に決定されるという仕組みを指しており、一つのメソッド名からその実行時状態に合わせた個別のメソッド処理が呼び出されるようにするという演繹的意味と、各クラスの同種機能メソッドを一つの共通メソッドにまとめて実行時状態に合わせたメソッド処理が呼び出されるようにするという帰納的意味がある。
その実装としては[[オーバーライド|メソッドオーバーライド]]機能を活用した仮想関数と、実行時[[パターンマッチング]]機能を活用した総称関数の二つが挙げられる。{{仮リンク|仮想メソッド(OOP)|en|Virtual function|label=仮想関数}}はスーパークラスの抽象メソッドの呼び出しを、それを[[オーバーライド]]したサブクラスの実体メソッドの呼び出しにつなげるという動的ディスパッチ機能である。{{仮リンク|総称関数|en|generic function}}はオブジェクトの実行時[[パターンマッチング]]を使用する独立関数であり、その引数にされた各オブジェクトの型(=クラス)の組み合わせに従って実行コードブロックを選択決定するという[[多重ディスパッチ]]機能である。
=== コンポジションとデリゲーションとジェネリクス ===
{{仮リンク|オブジェクトコンポジション|en|Object composition|label=コンポジション (合成)}}と[[委譲|デリゲーション]](委譲)は、[[継承 (プログラミング)|継承]]を帰納的に分解した仕組みと言えるものであり、または合成と委譲による連携を演繹的に最適化した仕組みが継承であるとも言える。OOPにおける合成と委譲は、OOP原点の[[Smalltalk]]が[[Simula|Simula67]]発の継承機能をオブジェクトの再帰構成という観点から再解釈したものがデザイン上のルーツになっている。継承は例外も多いが[[Is-a]]の委譲であるのに対して、合成は[[Has-a]]の委譲と読み替えることができる。
合成とは、特定処理の委譲先になる部品クラスの1個以上を持たせたクラス構造であり、そのクラスがとある処理を要求されてそれに対応できるデータ/メソッドを持っていない場合は、それに対応できる部品クラスを選択して処理を委譲するという仕組みである。その要求判別と選択過程を自動サーチ化したものが継承であり、部品クラスを基底クラスに置き換えて暗黙の委譲先にしたものである。しかしその自動サーチは、クラス階層に分散配置されているデータ/メソッドのどれが実際にアクセスされるのかという把握を困難にしたので、ここで差分プログラミング用途の継承の欠点が取り沙汰されるようになり、2000年代になるとクラスの機能拡張と分類体系化では、継承と合成の使い分けが重視されるようになった。
[[ジェネリックプログラミング|ジェネリクス]](総称化)は、オブジェクトの[[データ構造]]を汎用化して、それに汎用[[アルゴリズム]]の数々を適用できるようにした技術である。様々なデータ要素を内包するコンポジション(合成)オブジェクトは[[コンテナ (データ型)|コンテナ]](List/Set/Mapなど)と呼ばれ、その要素の型を型変数化することで汎用的な[[データ構造]]を表現し、その要素の型はコンテナのインスタンス化時に与えられる型パラメータによって決定される。ジェネリクスは[[データ構造]]と[[アルゴリズム]]の柔軟な[[ソフトウェアコンポーネント|コンポーネント化]]を促進させた。また、[[圏論]]の[[圏 (圏論)|圏]]に見立てられた[[コンテナ (データ型)|コンテナ]]および[[対象 (圏論)|対象]]に見立てられたデータ要素の入れ子構造と、[[射 (圏論)|射]]に見立てられた[[派生型|サブタイピング]]の融合は、[[共変性と反変性 (計算機科学)|共変性と反変性]]の手法に発展した。
=== 動的ディスパッチとメッセージパッシング ===
{{仮リンク|動的ディスパッチ|en|Dynamic dispatch}}は、OOPの[[ポリモーフィズム]]の
メッセージパッシングでは
===
[[インタフェース (抽象型)|インターフェース]]は、[[カプセル化]]を更に突き詰めた概念であり、[[継承 (プログラミング)|継承]]の[[派生型|サブタイピング]]用法を更に突き詰めた概念である実装(implementation)を体現している仕組みである。インターフェースは、[[オブジェクト (プログラミング)|オブジェクト]]の情報隠蔽とデータ抽象とメソッド抽象を合わせて表現する。[[クラス (コンピュータ)|クラス]]から見たインターフェースは、自身のサービスのモデリングであり、この作法は実現(realization)と呼ばれる。OOPの[[インタフェース (抽象型)|インターフェース]]は、基本的には抽象メソッドのみで構成される[[抽象型]]と定義されている。[[ソフトウェアコンポーネント]]間の相互通信媒体として用いられることが多く、[[SOLID|SOLID原則]]の重視に伴ないクラス間の[[結合度|結合]]にも多用される。
各言語での導入様式としては、抽象メソッドのみで構成される純粋抽象クラスが基本形にされており、インスタンス化はできない継承専用クラスになる。多重継承が前提にされている。インターフェースの抽象メソッドのメソッド内容(実行コードブロック)は、それを実装したクラスの同名メソッドで記述されることになる。インターフェースの各抽象メソッドはセッター・ゲッター・プロセスなどとして動作し、その実装内容は利用者側からは隠されて実行時のその都度に決定されることになる。
=== 多重ディスパッチとミックスインとトレイト ===
[[多重ディスパッチ]]は、オブジェクトの{{仮リンク|振る舞いサブタイピング|en|Behavioral subtyping}}を、オブジェクトの実行時[[パターンマッチング]]に置き換えた[[ポリモーフィズム]]・アプローチである。サブタイピングが同名アルゴリズムを個々の派生クラスに分散記述するのに対して、多重ディスパッチは個々の派生クラスの同名アルゴリズムを独立関数内で一括記述する。その独立関数が多重ディスパッチではメソッドと呼ばれるが、正確にはディスパッチ先になる個々の実行コードブロックがメソッドであり、その多重定義で総称メソッド({{仮リンク|総称関数|en|generic function}})と呼ばれる。総称メソッドは1個以上のオブジェクトを引数にし、その各引数オブジェクトの型(クラス)の組み合わせに従って、実行コードブロックを選択決定(ディスパッチ)する。その型[[パターンマッチング]]では、クラスに付加された[[アノテーション]]識別([[マーカーインタフェース|マーカーインターフェース]])の方が重視されることもあり、これがアドホック多相とサブタイプ多相の双方で継承を解釈できる[[ミックスイン]]の原点になっている。
[[ミックスイン]](Mix-in)は、[[スーパークラス (計算機科学)|上位クラス]]からの機能取得と[[サブクラス (計算機科学)|下位クラス]]への機能注入を主体にした[[継承 (プログラミング)|継承]]アプローチであり、そこでは上位クラスと下位クラスの[[Is-a関係]]が軽視されていることも特徴である。これは[[サブタイプ|サブタイピング]]特化の実装継承とは反対に、差分プログラミング用法に特化させた継承と言えるものである。ただしこの差分プログラミングはあくまで[[メソッド (計算機科学)|メソッド]]限定である。こちらも[[多重継承]]が前提であり、インスタンス化はできない継承専用クラス(Mix-inクラス)を扱っている。Mix-inクラスの代表的な実装形態は[[トレイト]]である。トレイトはメソッドの集合体であり、そのメソッド集合を一つの機能にした分類体系化が可能であり、そのメソッド間で状態を共有するためのデータメンバも所有できることがある。トレイトは機能注入用のメソッド実体と、[[オーバーライド]]用の[[関数プロトタイプ|メソッド定義]]の双方を持てるが、[[インタフェース (抽象型)|インターフェース]]とは異なり前者のメソッド実体の方が中心である。Mix-inの設計は各言語で多様化しており、Mix-inクラスは各言語によって[[トレイト]]・モジュール・ロール・プロトコル・[[型クラス]]などの様々な形態で導入されている。クラスをそのままMix-in化できる言語もあり、[[関数オブジェクト]]をMix-in化できる言語もあり、メソッド実装も可能にしたインターフェースをMix-in化できる言語もある。[[トレイト]]のMix-inは{{仮リンク|構造的型付け|en|Structural type system}}で扱われることが多く、従来の[[クラス (コンピュータ)|クラス]]の継承と[[インタフェース (抽象型)|インターフェース]]の実装が{{仮リンク|記名的型付け|en|Nominal type system}}で扱われることと対比されている。
== 歴史 ==
1954年に初の[[高水準言語]]・[[FORTRAN]]が登場すると、開発効率の劇的な向上と共にソフトウェア要求度も自然と高まりを見せてプログラム規模の急速な拡大が始まった。それに対応するために肥大化したメインルーチンを[[サブルーチン]]に分割する手法と、[[スパゲティプログラム|スパゲティ化]]した[[Goto文|goto命令]]を[[制御構造|制御フロー構
=== Simulaの開発(1962 - 72) ===
1962年、ノルウェー計算センターで[[モンテカルロ法]]シミュレーションを運用していた計算機科学者[[クリステン・ニゴール]]は、[[ALGOL|ALGOL60]]を土台にしてProcessと呼ばれる[[コルーチン]]機構を加えたプログラミング言語「[[Simula]]」を
=== 構造化プログラミングの提唱(1969 - 75) ===
1974年に[[MIT]]の計算機科学者[[バーバラ・リスコフ]]は「[[抽象データ型]]」という
=== Smalltalkとオブジェクト指向の誕生(1972 - 81) ===
Simula発のProcessとクラスの示した可能性は、[[パロアルト研究所]]の計算機科学者[[アラン・ケイ]]による「メッセージング」という考え方のヒントになった。ケイはプログラム内のあらゆる要素をオブジェクトとして扱い、オブジェクトはメッセージの送受信でコミュニケーションするという独特のプログラム理論を提唱した。それには従来の関数呼び出しをセレクタの実行時解釈に置き換えて積極的な[[委譲]]を推進するメッセージ式と、プログラムコードとしても解釈できるデータ列を送信してそれを任意のタイミングで評価(eval)することで新たなデータを導出できるなどのアイディアが盛り込まれていた。これらの遅延結合パラダイムは非同期通信や単方向通信への可能性をも開いており、この発想の背景には[[LISP]]の影響があった。メッセージを駆使するオブジェクトの構築には、Simula発のそれに[[プラトン]]の[[イデア論]]を重ね合わせた[[クラス (コンピュータ)|クラス]]と[[インスタンス]]の仕組みが導入された。オブジェクトとメッセージングの構想に基づいて開発された「[[Smalltalk]]」はプログラミング言語と[[GUI]]フレームワークを併せたものとなり、1972年に[[データゼネラルNova]]上での1000行程度のBASICを使った試作(概念実証)を経て、翌1973年に新開発された[[Alto|ゼロックスAlto]]上で本格稼働された。Smalltalkの設計を説明するためにケイが考案した「[[オブジェクト指向]]」という用語はここで初めて発信された。またケイのメッセージング構想は[[MIT]]の計算機科学者[[カール・ヒューイット]]に能動的な[[プロセス代数]]を意識させて<ref name="アクター">“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.”[https://dl.acm.org/doi/abs/10.1145/512927.512942|Actor Induction and Meta-evaluation]</ref>、1973年発表の[[アクターモデル]]のヒントにもなっている。しかし委譲の多用とデータ列が常にコード候補としても扱われる処理系は、当時のコンピュータには負荷が大きく実用的な速度を得られないという問題にすぐ直面した。Smalltalk-74(新たに開発された[[BitBLT]]を使った高速描画版Smalltalk-72)からSmalltalk-76の過程で、やむなくメッセージは(多くの場合)関数の動的コールに、メソッドはパターンマッチ処理から単なる関数へ置き換えられるなど構想時の柔軟さが失われるほど最適化された。また、ケイの留保した継承機構<ref name="継承">“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. ”[http://www.purl.org/stefan_ram/pub/doc_kay_oop_en|Dr. Alan Kay on the Meaning of “Object-Oriented Programming”]</ref>も導入されてオブジェクトは抽象データ型の性格も有するようになった。
1980年のSmalltalk-80は、元々はメッセージを重視していたケイを自嘲させるほど同期的で双方向的で手続き的なオブジェクト指向へと変貌していた。それでも動的ディスパッチと[[委譲]]でオブジェクトを連携させるスタイルは画期的であり、1994年に発表される[[デザインパターン (ソフトウェア)|デザインパターン]]の模範にもされている。1981年に当時の著名なマイコン専門誌『[[Byte (magazine)|BYTE]]』が、Smalltalkとその理念であるオブジェクト指向を紹介して世間の注目を集める契機になったが、ケイの思惑に反して技術的関心を集めたのはクラスの仕組みの方であった。オブジェクト指向は知名度を得るのと同時に、Simula発の[[クラス (コンピュータ)|クラス]]([[継承 (プログラミング)|継承]]と動的ディスパッチ)および[[抽象データ型]](データ抽象とデータ隠蔽)にマウントされて解釈されるようになり、それらのコンセプトがケイの構想とは無関係であったことから、オブジェクト指向の定義はケイの手を離れて独り歩きするようになった。
=== C++の開発と普及(1979 - 88) ===
[[Simula]]を研究対象にしていた[[ベル研究所|AT&Tベル研究所]]の計算機科学者[[ビャーネ・ストロヴストルップ]]は、1979年からクラス付きC言語の
1986年から[[Association for Computing Machinery|ACM]]が[[OOPSLA
=== コンポーネントとネットワーク(1989 - 97) ===
ネットワーク技術の発展に連れて、データとメソッドの複合体であるオブジェクトの概念は、[[分散システム]]構築のための基礎要素としての適性を特に見出される事になり、[[IBM|IBM社]]、[[Apple|Apple社]]、[[サン・マイクロシステムズ|サン社]]などが1989年に共同設立した[[Object Management Group|OMG]]は、企業システムネットワーク向け分散オブジェクトプログラミング規格となる[[CORBA]]を1991年に発表した。その前年に[[マイクロソフト|マイクロソフト社]]は[[ウェブアプリケーション]]向けの分散オブジェクトプログラミング技術となる[[OLE]]を発表し、1993年には[[Component Object Model|COM]]と称する[[ソフトウェアコンポーネント]]仕様へと整備した。この[[Component Object Model|COM]]の利用を眼目にしてリリースされた「[[Microsoft Visual C++|Visual C++]]」「[[Visual Basic]]」は[[World Wide Web|ウェブ]]時代の新しいプログラミング様式を普及させる先駆になった。この頃にデータ抽象、データ隠蔽、[[アクセスコントロール]]および[[インタフェース (抽象型)|インターフェース]]によるプログラムの抽象化は、総じて[[カプセル化]]の概念でまとめられるようになった。クラスの[[継承 (プログラミング)|継承]]が最もオブジェクト指向らしい機能と見なされていたのが当時の特徴であった。継承構造を利用した振る舞いサブタイピング及び動的ディスパッチは[[多態性]]という用語に包括された。こうしていわゆるオブジェクト指向の三大要素がやや漠然と確立されている。1996年にサン社がリリースした「[[Java]]」は三大要素が強く意識された[[クラスベース]]であり、その中の分散オブジェクト技術は[[JavaBeans|Beans]]と呼ばれた。類似の技術としてApple社も[[MacOS]]上で[[Objective-C]]などから扱える[[Cocoa]]を開発している。また、1994年から96年にかけて「[[Python]]」「[[Ruby]]」「[[JavaScript]]」といったオブジェクト指向スクリプト言語がリリースされ、従来の[[静的型付け]]に対する[[動的型付け]]と、[[クラスベース]]に対する新しい[[プロトタイプベース]]の認知度を高めている。
抽象化を旨とするオブジェクト指向ではそのプログラミング自体の抽象化も積極的に推進されている。80年代後半から立ち上げられた[[オブジェクト指向分析設計|オブジェクト指向分析]](OOA)や[[オブジェクト指向設計]](OOD)の各手法から導き出される[[コンセプトモデル|概念モデル]]を、多角的に[[フローチャート|チャート化]]ないし[[ダイアグラム|ダイアグラム化]]するための数々のオブジェクト指向開発方法論が[[OOPSLA]]界隈の識者たちから発表されるようになり、そこで用いられる[[形式言語]]は{{仮リンク|オブジェクトモデリング言語|en|Object-modeling language}}と呼ばれた。これはプログラミングのためのプロトタイプ(ひな型)として重視され、オブジェクト指向では[[モデリング言語]]と[[プログラミング言語]]が並んでソフトウェア開発の両輪になった。1994年にモデリング言語の代表的な活用例である[[ギャング・オブ・フォー (情報工学)|GOF]][[デザインパターン (ソフトウェア)|デザインパターン]]が初回発表され、後のオブジェクト指向学習では非常に重視されるようになった。1995年にモデリング言語の標準化を企図した[[統一モデリング言語|UML]]がOOPSLAで初回発表され、1997年に[[Object Management Group|OMG]]の標準モデリング言語として採用された。
==
ここではクラスベースの記述は省略している。
<div style="{{column-count|2}}">
* [[
* [[Smalltalk]] 1972年 動的・メッセージ式・純粋系
* [[
* [[Objective-C]] 1984年 静的と動的・メッセージ式
* [[
* [[
* [[Self]] 1987年 動的・プロトタイプベース・メッセージ式・純粋系
* [[Modula-3]] 1988年 静的
* [[Common Lisp]]([[CLOS]]) 1988年(ANSI規格化は1994年) 動的・多重ディスパッチ・[[The Art of the Metaobject Protocol|メタオブジェクト]]
<!-- :[[クラスベース]]のオブジェクト指向。メソッド記述の関数呼び出し形式への統合、[[多重ディスパッチ]]、クラスの動的な再定義等を特徴とする。-->
*
*[[Dylan]] 1992年 動的・多重ディスパッチ
*[[Lua]] 1993年 動的・プロトタイプベース
* [[
* [[
*[[Ada]] 1995年からOOP化 静的
*
* [[
*
* [[JavaScript]] 1996年(first released) 動的・プロトタイプベース
*[[OCaml]] 1996年 静的・関数型
*[[Squeak]] 1996年 動的・メッセージ式
*[[ECMAScript]] 1997年 動的・プロトタイプベース
*[[C Sharp|C#]] 2000年 静的と動的
*[[Visual Basic .NET|Visual Basic.NET]] 2001年 静的
*[[D言語]] 2001年 静的
*[[Io (プログラミング言語)|Io]] 2002年 動的・プロトタイプベース・メッセージ式・純粋系
*[[COBOL]] 2002年からOOP化 静的
*[[FORTRAN]] 2003年からOOP化 静的
*[[R言語]] 2003年からOOP化 動的・関数型・多重ディスパッチ
* [[Scala]] 2003年 静的・関数型
*[[Groovy]] 2003年 動的
*[[PHP (プログラミング言語)|PHP]] 2004年からOOP化 静的と動的
*[[F Sharp|F#]] 2005年 静的・関数型
*[[MATLAB]] 2008年からOOP化 動的・関数型
*[[Go (プログラミング言語)|Go]] 2009年 静的
*[[Rust (プログラミング言語)|Rust]] 2010年 静的・関数型
* [[Kotlin]] 2011年 静的
*[[Ceylon]] 2011年 静的
*[[Dart]] 2011年 静的・関数型
*[[Elixir (プログラミング言語)|Elixir]] 2011年 動的・関数型
*[[Julia (プログラミング言語)|Julia]] 2012年 動的・関数型・多重ディスパッチ
* [[TypeScript]] 2012年 静的と動的・関数型
*[[Swift (プログラミング言語)|Swift]] 2014年 静的・プロトコル指向
*[[Raku]] 2015年 静的と動的
</div>
==
ここでは日本語ページ化されている項目のみ列挙している。
<div style="{{column-count|3}}">
* [[クラスベース]]
*[[プロトタイプベース]]
*[[メッセージ (コンピュータ)|メッセージ]]
*[[クラス (コンピュータ)|クラス]]
*[[インスタンス]]
*[[フィールド (計算機科学)|フィールド]]
*[[プロパティ (プログラミング)|プロパティ]]
*[[メソッド (計算機科学)|メソッド]]
* [[インスタンス変数]]
* [[クラス変数]]
*
*
*
* [[継承 (プログラミング)|継承]]
*[[ポリモーフィズム|多態性]]
*[[This (プログラミング)|This]]
* [[
* [[
*
*[[ダックタイピング]]
*
*[[スーパークラス (計算機科学)|スーパークラス]]
*[[サブクラス (計算機科学)|サブクラス]]
*[[抽象クラス]]
*[[メタクラス]]
*
*[[仮想関数テーブル]]
*[[菱形継承問題]]
*[[仮想継承]]
*[[インタフェース (抽象型)|インターフェース]]
*[[トレイト]]
* [[抽象型]]
*[[オブジェクト型]]
*[[型クラス]]
*[[委譲]]
*[[多重ディスパッチ]]
*[[ダブルディスパッチ]]
*[[多重定義|オーバーロード]]
*[[アノテーション]]
*[[コンテナ (データ型)|コンテナ]]
*[[ボックス化]]
*[[ジェネリクス]]
*[[共変性と反変性 (計算機科学)|共変性と反変性]]
*[[モジュール]]
*[[ソフトウェアコンポーネント]]
*[[リフレクション (計算機科学)|リフレクション]]
*[[モンキーパッチ]]
*[[メッセージ転送]]
*[[型システム]]
*[[オブジェクト指向分析設計]]
*[[オブジェクト指向モデリング]]
*[[統一モデリング言語|UML]]
*[[契約による設計]]
*[[デザインパターン (ソフトウェア)|GOFデザインパターン]]
*[[GRASP]]
* [[SOLID]]
</div>
== 脚注 ==
|