「オブジェクト指向プログラミング」の版間の差分
削除された内容 追加された内容
タグ: 取り消し |
|||
(同じ利用者による、間の28版が非表示) | |||
6行目:
{{プログラミング言語|index=おふしえくとしこうふろくらみんく}}
[[ファイル:Object oriented design object.jpg|境界|右|フレームなし]]
'''オブジェクト指向プログラミング'''(オブジェクトしこうプログラミング、{{Lang-en-short|''object-oriented programming''}}、略語:OOP)は、'''[[オブジェクト指向]]
オブジェクト指向プログラミングという言葉自体は、計算機科学者[[アラン・ケイ]]
== 特徴 ==
#[[カプセル化]](''encapsulation'')
#[[継承 (プログラミング)|継承]](''inheritance'')
#[[ポリモーフィズム|多態性]](''polymorphism'')
#[[メッセージ (コンピュータ)|メッセージ・パッシング]](''message passing'')
#[[ダイナミックバインディング|遅延バインディング]](''late binding'')
=== カプセル化 ===
=== 継承 ===
既存オブジェクトのデータ構成とメソッド構成を引き継いで、新しい派生オブジェクトを定義する仕組みが継承と呼ばれる。引き継ぐ際には新たなデータとメソッドを自由に追加できるので、派生オブジェクトの構成は既存内容+追加内容になる。継承構造は、既存束縛で真になる式は派生束縛でも真になるという[[リスコフの置換原則]]を遵守する。オブジェクトはソースコード上ではクラスとして定義されるので、継承元の親クラスはスーパークラス、継承先の子クラスはサブクラスと呼ばれる。クラスは自身のスーパークラスを複数個指定する事もできる。一つのスーパークラスを継承するのは単一継承、複数のスーパークラスを継承してそれぞれの構成内容を引き継ぐのは多重継承と呼ばれる。継承とは本質的に異なるが、多重の仕組みは後述の[[インタフェース (抽象型)|インターフェース]]の実装で重視されており{{仮リンク|インターフェース分離の原則|en|Interface segregation principle|label=}}に活用されている。
=== 多態性 ===
異なる種類のオブジェクトに同一の操作インターフェースを持たせる仕組みが多態性と呼ばれる。オブジェクト指向下の多態性は、クラスの派生関係またはオブジェクトの動的バインディングを利用した実行時変化プロセスである{{仮リンク|サブタイピング|en|subtyping|label=}}を指す。サブタイピング(派生型付け)は{{仮リンク|仮想関数(OOP)|en|Virtual function|label=仮想関数}}、[[多重ディスパッチ]]、{{仮リンク|動的ディスパッチ|en|Dynamic dispatch|label=}}の三手法に分類される。最もよく知られる仮想関数は多態性と同義に説明される事が多い。'''仮想関数'''は、メソッドが所属するクラスの派生関係のみに焦点を当てたシングルディスパッチであり、スーパークラス[[関数プロトタイプ|抽象メソッド]]への呼び出しから、その実行時のサブクラス実装メソッドに多方向分岐させるプロセスを指す。その際は[[Vtable]]と呼ばれる[[関数へのポインタ]]に近い仕組みが用いられる。抽象メソッドの使用は[[依存性逆転の原則]]に準じたものであり、それを中継点にした具体的メソッドの実装は[[開放/閉鎖原則|開放閉鎖の原則]]を体現するものである。'''多重ディスパッチ'''は、メソッドが所属するクラスの派生関係に加えて、メソッドの各引数のクラスの派生関係にも注目した形態である。各引数は実行時に[[ダウンキャスト|型ダウンキャスト]]されて、その引数の型パターンに対応したルーチンに分岐する。メソッド所属クラスの派生関係が絡まない場合は単一引数だとシングルディスパッチになる。多重ディスパッチの中でもプロセス分岐に関与するクラスが二つに限定されたものは[[ダブルディスパッチ]]と個別定義されている。'''動的ディスパッチ'''は、[[プロトタイプベース]]のOOPで用いられるものであり、実行時におけるオブジェクトのメソッド参照の切り替えカスタマイズによるプロセス変化を指す。また、[[クラスベース]]のOOPでもクラスの定義内容を操作できる[[リフレクション (情報工学)|リフレクション]]機能によってこれが再現される事もある。
=== メッセージ・パッシング ===
{{Quotation|''I thought of objects being like biological cells and/or individual computers on a network, only able to communicate with messages.''
(さながら生物の細胞、もしくはネットワーク上の銘々のコンピュータ、それらはただメッセージによって繋がり合う存在、僕はオブジェクトをそう考えている)|Alan Kay}}{{Quotation|''... each object could have several algebras associated with it, and there could be families of these, and that these would be very very useful.''
(銘々のオブジェクトは自身に伴う幾つかの「代数」を持つ、またそれらの家族たちもいるかもしれない、それらは極めて有用になるだろう)|Alan Kay}}{{Quotation|''The Japanese have a small word - ma ... The key in making great and growable systems is much more to design how its modules communicate rather than what their internal properties and behaviors should be.''
(日本語には「間」という言葉がある・・・成長的なシステムを作る鍵とは内部の特徴と動作がどうあるべきかよりも、それらがどう繋がり合うかをデザインする事なんだ)|Alan Kay}}
===
{{Quotation|''I realized that the cell/whole-computer metaphor would get rid of data,'' ...
(僕はこう気付いた、細胞であり全体でもあるコンピュータメタファーはデータを除去するであろうと、)|Alan Kay}}{{Quotation|''... there were two main paths that were catalysed by Simula. The early one (just by accident) was the bio/net non-data-procedure route that I took. The other one, which came a little later as an object of study was abstract data types, and this got much more play.''
(''Simula''を触媒にした二本の道筋があった。初めの一本は細胞組織的な非データ手法、僕が選んだ方だ。少し遅れたもう一本は抽象データ型、こっちの方がずっと賑わってるね。)|Alan Kay}}
== 歴史 ==
87 ⟶ 61行目:
[[1980年]]代後半に次々と生まれたオブジェクト指向分析・設計論は、[[Smalltalk]]を源流とするオブジェクト指向を基に組み立てられた。そのころSmalltalkは商用展開こそされていたが広く普及しているとは言えず、一般には[[C++]]での[[実装]]が多くを占めた。しかしC++はSmalltalkと思想的にかなり異なる点や、同様のことを実現する際の実装面での複雑さや制約が問題とされた。このニーズを受けC++の提示した抽象データ型にクラスを適用する現実的な考え方と親しまれたALGOL系の構文を踏襲しつつ、内部的には柔軟なSmalltalkのオブジェクトモデルを採用し、'''メソッド'''などの一部用語やリフレクション、実行時動的性などSmalltalk色も取り入れた[[Java]]が注目を集めた([[1995年]]に登場。元々はモバイル機器向け言語処理系として開発された)。程なくSmalltalkやSELFで達成された[[仮想機械|仮想マシン(バイトコードインタープリタ)]]高速化技術の転用により実用的速度を得、バランス感覚に長けたJavaの台頭によって[[オブジェクト指向開発]]に必要な要素の多くが満たされ、[[1990年代]]後半からオブジェクト指向は広く普及するようになった。
==
[[ファイル:History of object-oriented programming languages.svg|サムネイル|
オブジェクト指向を総体的または部分的にサポートする機能を備えたプログラミング言語の公開は、1980年代後半から
[[クラスベース]]では「C++」「Java」「C#」「Swift」 ;[[Simula|Simula 67]] 1967年
:1962年に公開された[[Simula]]の後継版であり、[[クラス (コンピュータ)|クラス]]のプログラ
;[[Smalltalk]] 1972年
:[[メッセージパッシング]]のプログラ
;[[C++]] 1983年
:[[C言語]]に
;[[Objective-C]] 1984年
:[[C言語]]
;[[Object Pascal]] 1986年
:[[Pascal]]にクラスベースのオブジェクト指向を
;[[Eiffel]] 1986年
:[[Pascal]]にクラスベースのオブジェクト指向を追加したもの。[[契約プログラミング]]方針と厳格な名前付け方針による静的型付けを重視した言語である。引数パターンによる[[オーバーローディング]]が除外されている。継承されたクラス名はその都度ユニーク名にクローンされて[[菱形継承問題|多重継承時の問題]]を回避している。自動メモリ管理の[[ガーベジコレクション|ガーベジコレクタ]]の導入も特徴であり堅牢性が重視されている。なお、[[ジェネリックプログラミング]]も採用されており利便性も図られている。
;[[Self]] 1987年
:メッセージ
;[[CLOS]] 1988年
:[[Common Lisp]]にクラスベースのオブジェクト指向を
;[[Python]]
:[[プロトタイプベース]]と[[クラスベース]]の双方を兼ねたオブジェクト指向スクリプト言語。[[インタプリタ]]式で動作する。動的型付けを重視している。従来の型宣言制約を緩めた[[ダイナミックバインディング|動的バインディング]]の柔軟性が扱いやすく奥の深いオブジェクト指向プログラミングを実現している。言語仕様が比較的簡素化され、[[ガベージコレクション|ガーベジコレクション]]も実装されており高い堅牢性を持つ。[[リフレクション (情報工学)|リフレクション]]に相当するクラスと関数のメタデータ・カスタマイズは利便性に加えて保守性をも向上させた。後のオブジェクト指向スクリプト言語の手本になり、2019年現在ではJavaを凌ぐ人気を博すようになった。
;[[Java]] 1995年
:[[C++]]をモデルにしつつ堅牢性と
;[[Delphi]] 1995年
:[[Object Pascal]]を発展させたもので、データベースの操作プログラム開発などを主な用途とした。一時期Javaの対抗馬
;[[Ruby]] 1995年
:[[Python]]を意識して開発されたオブジェクト指向スクリプト言語。日本で誕生してグローバル化したプログラミング言語である。動的型付けを重視している。[[Mixin|ミックスイン]]の採用が特徴である。
;[[JavaScript]] 1996年
:[[ウェブアプリケーション|WEBアプリケーション]]開発を主な目的
;[[C Sharp|C#]] 2000年
:[[Java]]を強く意識してマイクロソフト社が開発
;[[Scala]] 2003年
:クラスベースのオブジェクト指向と関数型プログラミングを連携させた言語。オブジェクトは関数の引数または返値として扱われる対象データ存在になるだけでなく、オブジェクトにもラムダ計算的解釈が適用できるので主体的な評価式存在にもなれる。関数、オブジェクト、オブジェクトメソッドの三者にそれぞれ高階関数、第一級関数、評価式の役割を自在に演じさせてモナド的な関数連鎖を織りなす柔軟なプログラミングが可能である。結果的に関数型と抽象データ型の親和性を世に証明する言語になった。
;[[Kotlin]] 2011年
:[[Javaバイトコード]]を出力し、[[Java仮想マシン]]上で動作するJavaテクノロジー互換
;[[TypeScript]] 2012年
:[[JavaScript]]を強く意識してマイクロソフト社が開発したオブジェクト指向スクリプト言語。Typeの名は、静的型付けを再び取り上げて動的型付けと合わせて活用するための漸進的型付けの提唱に因んでいるようである。
;[[Swift (プログラミング言語)|Swift]] 2014年
:
== 用語と解説 ==
=== クラス ===
{{main|クラス (コンピュータ)}}
==== クラスベース ====
{{main|クラスベース}}
'''クラス''' (class) は大多数のオブジェクト指向プログラミング言語で提供されている仕組みであり、上記の機能のほとんど全てに関わりがある。概念的にはクラスはオブジェクトの種類を表す。このためオブジェクトはクラスに'''属する'''という言い方をする。あるクラスに属するオブジェクトのことをそのクラスの'''インスタンス''' (instance) と呼ぶ。[[データ型]]の理論から見た場合クラスは型を定義する手段の一つである。クラスによってオブジェクトを記述する言語を'''[[クラスベース]]''' ({{Lang|en|class-based}}) のオブジェクト指向プログラミング言語と呼ぶ。
232 ⟶ 133行目:
クラスベースの言語との関係について考えてみると、クローンはプロトタイプと同一の「クラス」に属すると見なし、データ・メンバやメソッドが追加・削除されてあらたなプロトタイプが作られると別の「クラス」が内部的に生成されると考えることができる。ここでデータ・メンバやメソッドの追加のみを許して削除を許さないよう制限すればクローンの「クラス」がその親の「クラス」を継承した場合と同等になる。このためメッセージが委譲の連鎖をたどって配送されるという効率上の問題を無視すれば理論上、インスタンス・ベースの言語の記述能力はクラス・ベースの言語を包含していると言える。ただ、インスタンス・ベースの言語でも実行効率上の問題からなんらかのクラスに似た仕組みを備えている場合が多い。
==== データメンバ ====
'''データメンバ''' ({{Lang|en|data member}}) は、他のオブジェクトに対する[[参照 (情報工学)|参照]]や[[ポインタ (プログラミング)|ポインタ]]であるか、他のオブジェクトそのものである。参照かポインタである場合にはそのデータメンバの参照するのはデータメンバが記述されているクラスそのもののインスタンスに対する参照であっても良い。
一般にデータメンバは'''インスタンスデータメンバ'''('''[[インスタンス変数|インスタンスフィールド]]''')と'''クラスデータメンバ'''('''静的変数''')の2種類に大別できる。効率上の観点から言語が提供する基本オブジェクトの定数を表すデータメンバは特別扱いされる。そのような定数を表すデータメンバを特に'''定数データメンバ''' ({{Lang|en|constant data member}}) と呼ぶ。データメンバは[[C++]]などの言語では'''メンバ変数''' ({{Lang|en|member variable}})、[[Java]]などでは'''フィールド'''と呼ばれることがあり、[[統一モデリング言語|UML]]では[[属性]]と呼ばれる。
インスタンスデータメンバ(一般に単にデータメンバと言われる場合はこちら)はそのクラスのインスタンス各々に保持される。インスタンスデータメンバの集まりはそのクラスのインスタンスが保持するデータの形式を定める。インスタンスデータメンバは単にデータメンバと呼ばれることも多い。
247 ⟶ 147行目:
クラスデータメンバはそのクラスオブジェクトとインスタンスオブジェクトの間で共有されるデータである。
[[Smalltalk]]ではクラスデータメンバは'''[[クラス変数]]''' ({{Lang|en|class variable}}) と呼ばれる。また、[[C++]]・[[Java]]では歴史的事情によりクラスデータメンバは'''静的データメンバ''' ({{Lang|en|static data member}})、'''静的変数''' (static variable)、'''静的フィールド''' ({{Lang|en|static field}}) と呼ばれる。ただし、Smalltalkのクラス変数はC++やJavaのクラス変数とは異なる。Smalltalkにおいて、C++やJavaのクラス変数と同等となる変数は'''プール辞書''' ({{Lang|en|pool dictionary}}) と呼ばれる。
==== メソッド ====
'''[[メソッド (計算機科学)|メソッド]]''' ({{Lang|en|method}}) は特定の種類のメッセージの処理方法を記述したものである。メソッドも[[メソッド (計算機科学)#インスタンスメソッド|インスタンス・メソッド]]と[[メソッド (計算機科学)#静的メソッド|クラス・メソッド]]の2種にできる。インスタンス・メソッドはそのクラスの各インスタンスオブジェクトを操作し、クラス・メソッドはクラスオブジェクトを操作する。メソッドとの集まりはそのクラスのオブジェクトが処理可能なメッセージのカタログの機能を果たす。
257 ⟶ 155行目:
==== クラスメソッド ====
[[メソッド (計算機科学)#静的メソッド|クラス・メソッド]]だが、オブジェクト指向の本義に立ち返れば、クラス・メソッドがあるということはクラスがメッセージをレシーブできるという事になる。クラスがメソッドを持つことは便利だが、クラスをオブジェクトとすると実行効率に劣るため、双方の利点を享受できるこのような折中的仕様を取る言語は多い。
C++ではクラスはオブジェクトでは無いが、一方でクラスに属するメソッドは存在する。[[Eiffel]]ではクラスはオブジェクトでは無いためクラスのメソッドであるクラス・メソッドは存在しない。[[Smalltalk]]ではクラスもオブジェクトの一種であるため当然クラスはメソッドをもつ。
クラス・メソッドは、C++では'''静的メンバ関数''' ({{Lang|en|static member function}}) と呼ばれる。これはクラスがオブジェクトでない言語にとってはクラス・メソッドより正確な表現であり適切である。("static" とはCの'''static変数'''に由来し'''auto変数'''の対語である。関数コールによりスタック上に生成される関数インスタンスに依存しない変数と、インスタンス生成有無にかかわらず実行できる関数の類似による。)Javaではクラス・メソッドは'''静的メソッド''' ({{Lang|en|static method}}) とも呼ばれることもある。
==== コンストラクタとデストラクタ ====
初期化に利用されるメソッドを'''[[コンストラクタ]]'''あるいは'''構築子''' ({{Lang|en|constructor}})、廃棄時に利用されるメソッドを'''[[デストラクタ]]'''と呼んで特別に扱うことが多い。コンストラクタが初期化だけを担う場合はイニシャライザあるいは初期化子 ({{Lang|en|initializer}}) と呼ばれることもある。Javaはオブジェクトの寿命管理に[[ガベージコレクション]]を用いるため、デストラクタをサポートしない。ただし、オブジェクトがガベージコレクションによって破棄されるときに呼び出される'''[[ファイナライザ]]''' ({{Lang|en|finalizer}}) をサポートし、{{Javadoc:SE|name=Object#finalize()|java/lang|Object|finalize()}}メソッドがその役割を果たす。ただし、ファイナライザはC++のデストラクタと違ってユーザーコードで明示的に呼び出すことはできない。ファイナライザが呼び出されるタイミングをプログラマが制御することはできず、最終防壁(フェイルセーフ)としての役割しか持たないため、Javaにおけるファイナライザは本当に必要でない限り使用するべきではない。C#もファイナライザをサポートする(構文はC++のデストラクタに似ており、かつてはデストラクタと呼ばれていたが、役割はJavaのファイナライザと同じである)。
[[データ型]]の理論においては保持されるデータが必ずその型で認められる正しい値の範囲に収まることを保証するため、生成されるオブジェクトのデータ・メンバが必ず適切なコンストラクタによって初期化されるように求める。またオブジェクトが入出力機器や[[ファイル (コンピュータ)|ファイル]]や通信、[[プロセス]]や[[スレッド (コンピュータ)|スレッド]]、[[ウィンドウ]]と[[ウィジェット (GUI)|ウィジェット]]など[[ハードウェア]]や[[オペレーティングシステム]] (OS) が提供する資源を管理するために利用される場合に、コンストラクタやデストラクタでそれらの資源の使用開始(オープン処理)や使用終了(クローズ処理)をそれぞれ管理し、通常のメソッドでそれらにまつわる各種サービスを提供するようにすることで、それらのリソースがあたかもプログラム中のオブジェクトであるかのように自然に取り扱うことができるようになる([[RAII]])。
287 ⟶ 168行目:
C++やJavaなどでは、コンストラクタはクラスと同じ名前を持ち、戻り値を持たないメソッドとして定義される。C++では一部のコンストラクタは[[型変換演算子]]として、また[[暗黙の型変換]]にも利用される。
====
動的型付けを採用するオブジェクト指向言語の多くは、クラスより生成するインスタンスの他に[[メタクラス]]という機能を持ちクラス自体をオブジェクトとして扱うことが出来る。このためオブジェクトには、インスタンスオブジェクトとクラスオブジェクトという2種類のオブジェクトが存在する。Java等クラスオブジェクトを持たない言語の文化圏では、インスタンスオブジェクトとオブジェクトを混同して説明される事があるが、Objective-CやPython、Ruby等、インスタンスオブジェクトとクラスオブジェクトが別であるオブジェクト指向言語では区別して説明される。<ref>Objective-Cプログラミ
ング言語[https://developer.apple.com/jp/devcenter/ios/library/documentation/ObjC.pdf]</ref>
<ref>Classes ― Python v2.7.3 documentation[http://docs.python.org/2/tutorial/classes.html]</ref>
<ref>クラス/メソッドの定義 (Ruby manual) [http://www.ruby-lang.org/ja/old-man/html/_A5AFA5E9A5B9A1BFA5E1A5BDA5C3A5C9A4CEC4EAB5C1.html]</ref>元々はSmalltalkから始まった用語である。
====
{{seealso|this (プログラミング)}}
そしてあるオブジェクトOにメッセージを配送し適切なメッセージ処理コード(振る舞い)を呼び出す際には、まず対象となるオブジェクトOについて共通部分の格納場所を見つけて適切なコードを選び出し、次にそのコードに対して処理対象となるオブジェクトO固有のデータの所在を示す'''オブジェクトID'''を渡すようになっている。
各オブジェクトの固有データを識別するオブジェクトIDを表現する方法も様々で、オブジェクトのIDとしては名前、番号なども用いられることがあるが、オブジェクトの固有データを記憶している[[主記憶]]上の[[メモリアドレス|アドレス]]がそのまま用いられることもある。アドレスを直接利用することは非常に実行効率の向上に寄与するが、プログラム間でのオブジェクトの受け渡し、セッション間(プログラムが終了して再度起動された時など)でのオブジェクトの受け渡しにはそのまま利用することができない。また各オブジェクトの固有データから共通部分の格納場所を見つける方法もまた各言語により異なり、その言語の開発目的に応じて実に多種多様である。
==== アクセスコントロール ====
オブジェクト指向プログラミングにおいて、[[オブジェクト (プログラミング)|オブジェクト]]は、[[カプセル化]]されておりブラックボックスである。したがって、処理するメッセージのカタログ、つまりインタフェースだけが利用者に公開され、内部の詳細は隠されるのが基本である。しかし、あるクラスのインスタンスの内部だけで利用されるメソッドまで公開してしまうと、利用者にとって煩雑である。また、定数データ・メンバのようなものは一々メソッドでアクセスするようにせず公開してしまっても、カプセル化の利点は失われず効率的でもある。そこで、オブジェクトを定義するプログラマが各データ・メンバやメソッドについて公開・非公開を設定できる機能を用意している言語は多い。
例えば、Javaでは、データ・メンバやメソッドの宣言にpublicと指定すれば、他オブジェクトから自由に利用でき('''公開'''と呼ばれる)、privateと指定すればオブジェクト内だけで利用できるようになる('''非公開'''と呼ばれる)。しかし、ある機能を提供するのに、一個ではなく一群のクラスに属するオブジェクトでそれを記述するのが相応しい事例がある。そのような場合、関係する一群のオブジェクト間でだけデータ・メンバやメソッドを利用できれば便利である。それを可能にするための拡張がいくつか存在する。例えば、継承を利用しているときに、あるクラスが子孫にだけ利用を許可したいデータ・メンバやメソッドがある場合、Javaではprotectedを指定することでそれを実現できる('''限定公開'''と呼ばれる)。また、ある一群の機能を実現するクラスの[[ライブラリ]]で、その実現に関連するクラスに属するオブジェクトだけがデータ・メンバやメソッド利用できるようにしたい場合も考えられる。また、Javaでは、ライブラリを構成するクラス群を表現する'''[[パッケージ (Java)|パッケージ]]''' ({{Lang|en|package}}) という仕組みがあり、特に指定がない場合は同一パッケージに属するクラスのオブジェクト間でのみデータ・メンバやメソッドを相互に利用可能である。その他にも、[[デザインパターン (ソフトウェア)|デザインパターン]]の一つである[[Facade パターン]]では、この仕組みがテクニックとして応用されている。また、C++ではフレンド宣言という仕組みがあり、あるクラスで外部非公開に指定されているデータ・メンバやメソッドについて、その利用を許可するクラスや関数のリストをクラス内に列挙することができる。なお、public、private、protectedというキーワードは、多くのプログラミング言語で用いられているが、その示す意味は言語ごとに差異があるため、注意が必要である。
=== メッセージ ===
{{seealso|メッセージ転送}}'''メッセージ''' ({{Lang|en|message}}) はオブジェクト間の通信でやりとりされる情報である。メッセージはメッセージ種別を示すIDとメッセージの種別に応じた追加の情報からなる定まった形式を持つ。追加の情報はそれ自身が何らかのオブジェクトや[[オブジェクトのID]]である場合もある。メッセージの配送には大別して2つの方式がある
* 同期式 - オブジェクトがメッセージの送信を依頼すると相手が受信、処理して結果を返すまでそのオブジェクトは処理を中断して待つ。
* 非同期式 - オブジェクトがメッセージの送信を依頼した後、相手の応答を待たずにオブジェクトは処理を続行する。処理結果は別のメッセージとして返される。
両者とも一長一短がありどちらがすぐれているとは言えない。また並列・並行処理が可能な環境では一方の仕組みがあれば、それを利用してもう一方も実現可能である。一般的な傾向としては、メッセージの伝送や処理に時間が掛かる場合は非同期式の方が効率は良く、そうでない場合には同期式の方が挙動が分かりやすく利用しやすい。[[並列処理]]・[[並行処理]]システムを記述する言語や[[分散コンピューティング|分散システム]]を記述する言語ではOSなどが提供するメッセージ機能や自前の配送メカニズムを使って非同期式でメッセージが配送される場合もあるが、一般にオブジェクト指向プログラミング言語ではその多くが同一のプログラム内の通信であるので同期式のメッセージ配送が利用される。特に[[コンパイル]]されるタイプのオブジェクト指向プログラミング言語では、しばしば特別なメッセージ配送の仕組みを用意せず、特別な形式の関数の呼び出しでメッセージの配送を直接に表現する。即ち、各メソッドを内部的には関数として実現し、メッセージIDはメソッド名で表し、関数の第一引数としてオブジェクトIDを渡し(この第一引数は多くの言語で特別な記法で表される)、追加の引数としてメッセージの追加部分の情報を渡すのである。こうするとメッセージ送信は直接的なメソッドの関数呼び出しとして表せる。ただし、プログラムで[[継承 (プログラミング)|継承]]の仕組みが利用されている場合はプログラムのテキストからだけでは呼び出すべきメソッドが決定できない場合があるので、実行時にメソッドを決定するために[[メソッド・サーチ]]や[[仮想関数テーブル]]といった仕組みが必要となる。多くのプログラミング言語においてメッセージは、メソッド呼び出しの比喩でしかないことが多い。SmalltalkやObjective-Cの様な言語では、メッセージはメソッド呼び出しとは独立した機構として存在している。メッセージが機構として存在する言語では、メッセージをオブジェクトに送信した際、宛先のオブジェクトにメッセージで指定したメソッドが存在しない場合でもメッセージを処理することが出来る。これを利用し、メッセージの配送先を別のオブジェクトに指定したり、メッセージを一時保存したり、不要なメッセージを無視する等といったメッセージ処理が行われる。
== 脚注 ==
|