「オブジェクト指向プログラミング」の版間の差分
削除された内容 追加された内容
Baudanbau20 (会話 | 投稿記録) m Interwiki link written as an external link |
|||
(同じ利用者による、間の5版が非表示) | |||
11行目:
== 特徴 ==
#[[カプセル化]](''encapsulation'')
28行目:
=== メッセージパッシング ===
{{Quotation|''I thought of objects being like biological cells and/or individual computers on a network, only able to communicate with messages.''<br>(さながら生物の細胞、もしくはネットワーク上の銘々のコンピュータ、それらはただメッセージによって繋がり合う存在、僕はオブジェクトをそう考えている)|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.''<br>(銘々のオブジェクトは関連付けられた幾つかの「代数」を持つ、またそれらの系統群も持つかもしれない、それらは極めて有用になるだろう)|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.''<br>(日本語には「間」という言葉がある・・・成長的なシステムを作る鍵とは内部の特徴と動作がどうあるべきかよりも、それらがどう繋がり合うかをデザインする事なんだ)|Alan Kay}}{{Quotation|''I wanted to get rid of data. ... I realized that the cell/whole-computer metaphor would get rid of data,'' ...<br>(僕は
== 歴史 ==
1954年に初の[[高水準言語]]・[[FORTRAN]]が登場すると、開発効率の劇的な向上と共にソフトウェア要求度も自然と高まりを見せてプログラム規模の急速な拡大が始まった。それに対応するために肥大化したメインルーチンを[[サブルーチン]]に分割する手法と、[[スパゲティプログラム|スパゲティ化]]した[[Goto文|goto命令]]を[[制御構造|制御構造文]]に置き換える手法が編み出され、これらは1960年に公開された言語「[[ALGOL|ALGOL60]]」で形式化された。当時のALGOLは[[アルゴリズム]]記述の一つの模範形と見なされたが、それと並行して北欧を中心にした計算機科学者たちはより大局的な観点によるプログラム開発技法の研究を進めていた。
42 ⟶ 41行目:
=== Smalltalkとオブジェクト指向の誕生(1972 - 81) ===
SimulaのProcessおよび67年版からのクラスの仕様は、[[パロアルト研究所]]の計算機科学者[[アラン・ケイ]]によるオブジェクトと「メッセージ」というプログラム概念のヒントになった。ケイはプログラム内のあらゆる要素をオブジェクトとして扱い、オブジェクトはメッセージの送受信でコミュニケーションするという独特のプログラム理論を提唱した。メッセージとはプログラムコードとしても解釈できるデータ列のことであり、そのデータ列を評価(''eval'')することで新たなデータを導出できるという仕組みを意味していた。オブジェクトが受け取ったメッセージは任意のタイミングで評価できるので非同期通信、単方向通信(送りっぱなし処理)をも可能にしていた。この発想の背景には[[LISP]]の影響があった。オブジェクトとメッセージの構想に基づいて開発された「[[Smalltalk]]」はプログラミング言語と[[GUI]]運用環境を併せたものとなり、1972年に[[Alto|ゼロックスAlto]]上で初稼働された。Smalltalkの設計を説明するためにケイが考案した「[[オブジェクト指向]]」という用語はここで初めて発信された。またメッセージの構想は[[MIT]]の計算機科学者[[カール・ヒューイット]]に能動的な[[プロセス代数]]を意識させて、1973年発表の[[アクターモデル]]のヒントにもなっている。しかし、データ列が常にコード候補として扱われる処理系は、当時のコンピュータには負荷が大きく実用的な速度を得られないという問題にすぐ直面した。Smalltalk-74とSmalltalk-76の過程で、やむなくメッセージはセレクタ仕様の追加と共に構想通りの評価ができないほどシステム向けに最適化され、レシーバーは動的ディスパッチとメソッド仕様が中心になり、オブジェクトはクラス定義の存在感が大きくなった。{{Quotation|''Smalltalk is not only NOT its syntax or the class library, it is not even about classes. I'm sorry that I long ago coined the term "objects" for this topic because it gets many people to focus on the lesser idea.The big idea is "messaging".''
<br>(Smalltalkはその構文やライブラリやクラスをも関心にしていないという事だけではない。多くの人の関心を小さなアイディアに向かせたことから、僕はオブジェクトという用語を昔作り出したことを残念に思っている。大切なのはメッセージングなんだ。)|Alan Kay}}1980年のSmalltalk-80は、元々はメッセージを重視していたケイを自嘲させるほど同期的で双方向的で手続き的なオブジェクト指向へと変貌していた。それでも動的ディスパッチと[[委譲]]でオブジェクトを連携させるスタイルは画期的であり、1994年に発表される[[デザインパターン (ソフトウェア)|デザインパターン]]の模範にもされている。1981年に
=== C++の開発(1979 - 88) ===
49 ⟶ 48行目:
=== プロトタイプベースの考案(1985 - 90) ===
[[Smalltalk]]のオブジェクト指向は、[[アラン・ケイ]]がその影響を言及していた[[LISP]]コミュニティを逆に感化して、Smalltalkが提示したメタオブジェクトの概念を通したオブジェクト指向とLISP風プログラミングの連携に向けた構想が練られるようになった。LISPの基礎であるアトムとシンボル型に倣う形で、オブジェクトのメンバ変数名とメンバ関数名自体をその都度評価(''eval'')して実行時の内容を導出し、実際の変数参照や関数呼出につなげるというアイディアが生まれた。これは実装面では単に、フレームと呼ばれる動的配列のスロットに変数や関数のポインタを付け替えするという機構にまとめられた。識別子(変数名と関数名)がマッピングされたスロットも増設削減可能であり、原型クラスと継承クラスのポインタも加えられた。このメタオブジェクト設計を導入して1985年に[[MIT人工知能研究所]]の[[LISPマシン]]上で「Flavors」が実装された。LISPの視点から保有スロット識別子の構成による[[動的型付け]]が盛り込まれ、その構成をパーツ化して多重継承させる[[ミックスイン]]という設計が考案され、また実行時の逐次
=== コンポーネントとネットワーク(1989 - 97) ===
ネットワーク技術の発展に連れて、データとメソッドの複合体であるオブジェクトの概念は、[[分散システム]]構築のための基礎要素としての適性を特に見出される事になり、[[IBM|IBM社]]、[[アップル (企業)|アップル社]]、[[サン・マイクロシステムズ|サン社]]などが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]]と呼ばれた。類似の技術としてアップル社も[[MacOS]]上で[[Objective-C]]などから扱える[[Cocoa]]を開発している。また、1994年から96年にかけて「[[Python]]」「[[Ruby]]」「[[JavaScript]]」といったオブジェクト指向スクリプト言語がリリースされ、[[プロトタイプベース]]という新しいプログラミングスタイルを定着させている。1994年のGOF[[デザインパターン (ソフトウェア)|デザインパターン]]の発表と1997年の[[Object Management Group|OMG]]による[[統一モデリング言語|UML]]策定は、オブジェクト指向プログラミングの標準化を促進させた。{{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.''<br>(Simulaを触媒にした二本の道筋があった。初めの一本はバイオネットな非データ手法、僕が選んだ方だ。少し遅れたもう一本は抽象データ型、こっちの方がずっと賑わっている。)|Alan Kay}}
== 代表的なオブジェクト指向言語 ==
58 ⟶ 57行目:
[[ファイル:History of object-oriented programming languages.svg|境界|中央|フレームなし]]
;[[Simula|Simula 67]] 1967年
:1962年に公開された[[Simula]]の後継
;[[Smalltalk]] 1972年
:[[メッセージパッシング]]のプログラム概念を導入した最初の言語。数値、真偽値、文字列から変数、コードブロック、メタデータまでのあらゆる要素をオブジェクトとするアイディアを編み出した最初の言語でもある。オブジェクト指向という言葉はSmalltalkの言語設計を説明する中で生み出された。オブジェクトにメッセージを送るという書式であらゆるプロセスを表現することが目標にされている。[[メッセージ転送|メッセージレシーバー]]と[[委譲]]の仕組みは、形式化されていない動的ディスパッチと[[ダイナミックバインディング|動的バインディング]]相当のものであり[[プロトタイプベース]]の源流にもなった。GUI運用環境に統合された専用のランタイム環境上で動作させる設計も模範にされ、これは後に[[仮想マシン]]や[[仮想実行システム]]と呼ばれるものになる。
86 ⟶ 85行目:
:[[Java]]を強く意識してマイクロソフト社が開発したクラスベースのオブジェクト指向言語。C++の柔軟性と融通的を残しながら、[[テンプレートメタプログラミング]]的なコーディングサポートも加えてマルチパラダイムに発展させている。アドホック多相では拡張メソッド、インデクサ、演算子オーバーロードなどを備えている。パラメトリック多相ではジェネリクスの型変数の[[共変性と反変性 (計算機科学)|共変性と反変性]]、型引数の型制約などを備えている。サブタイプ多相はクラスは単一継承でインターフェースは多重実装と基本通りである。[[関数型言語|関数型構文]]では特にデリゲートの有用性が高い。基本は[[静的型付け]]であるが、動的束縛型と[[ダックタイピング]]による[[動的型付け]]の存在感が高められているので漸進的型付けの言語と見なされている。[[.NET Framework]]([[共通言語基盤]]=仮想実行システム)上で実行される。
;[[Scala]] 2003年
:[[クラスベース]]のオブジェクト指向と[[関数型プログラミング]]を融合させた言語。[[クラス (コンピュータ)|クラス]]機構と関数型の[[型システム]]に同等の比重が置かれており静的型付け重視である。[[ミックスイン]]相当の[[トレイト]]と[[ジェネリクス]]を連携させた多態性が重視されている。型変数の[[共変性と反変性 (計算機科学)|バリアンス]]、[[共変性と反変性 (計算機科学)|共変と反変]]双方の型境界、抽象タイプメンバ、ジェネリックトレイト、抽象クラスの組み合わせでオブジェクトを様々に[[派生型|派生型付け]]できる。シングルトンオブジェクトの役割が形式化されて従来のクラス静的メンバの新解釈にも用いられている。専用の定義書式により[[イミュータブル]]なオブジェクトが重視されている。上述の派生型付けスタイルとオブジェクト引数の[[逆写像|抽出]]構文とオブジェクトの[[パターンマッチング|パターンマッチング式]]
;[[Kotlin]] 2011年
:静的型付けの[[クラスベース]]のオブジェクト指向であるが、[[手続き型プログラミング]]に回帰しており、クラス枠外の関数とグローバル変数の存在感が高められている。クラスはpublicアクセスとfinal継承がデフォルトにされて、カプセル化と継承が公然と軽視されている。これによりインスタンスは手続き型の関数の対象値としての役割が強められ、その操作をサポートする関数型構文も導入されている。仮想関数と抽象クラスによる多態性は標準通りである。[[Java仮想マシン]]上で動作するJavaテクノロジ互換言語である。
100 ⟶ 99行目:
:プロトタイプ(''prototype'')の仕組みを中心にしたオブジェクト指向を[[プロトタイプベース]]と言う。プロトタイプベースで言われるオブジェクトとは、中間参照ポインタの動的配列を指す。この動的配列は一般にフレームと呼ばれる。中間参照ポインタは一般にスロットと呼ばれる。スロットにはデータメンバとメソッドの参照が代入されるので、オブジェクトはクラスと同様にデータメンバとメソッドをまとめたものになる。プロトタイプベースの実装形式は言語ごとに様々であるが基本は概ね以下のようになる。オブジェクトはプロトタイプオブジェクトとクローンオブジェクトに分かれる。前者はクラス、後者はインスタンスに当たるものである。前者はシステム提供プロトタイプとユーザー定義プロトタイプに分かれる。プログラマはシステム提供プロトタイプを派生させてユーザー定義プロトタイプを作成する。プロトタイプは規定または事前の設計に基づいたデータメンバとメソッドを保持しており、クローンオブジェクトのひな型になる。クローンはそのプロトタイプへの参照を保持しており、プロトタイプはその親プロトタイプへの参照を保持している。これは継承相当の機能になる。プロトタイプを複製してクローンオブジェクトが生成される。クローンオブジェクトはそのプロトタイプと同じデータメンバとメソッドを保持する事になるが、プロトタイプ専用に指定されたメンバは除かれる。クローンオブジェクトのメソッドは自由に付け替えできるので、これは多態性相当の機能になる。
;[[メッセージ (コンピュータ)|メッセージ]]
:オブジェクト指向で言われるメッセージ(''message'')は、複数の方面の考え方が混同されている曖昧な用語になっている。元々はSmalltalkから始まったメッセージ構文ベースのオブジェクト指向の中心機構である。以前はクラスベースの方でもメソッドの呼び出しをメッセージを送るという風に考えることが推奨されていた。メッセージはオブジェクトのコミュニケーション手段と標榜されているが、その忠実な実装内容はそれほど知られていないのが実情である。最も混同されているものに[[アクターモデル]]があるが、そこで言われる非同期性とオブジェクト指向で言われる
;[[インスタンス]]
:(''instance'')はクラスベースではクラスを実体化(量化)したものであり、実装レベルで言うとデータメンバと仮想関数テーブルをメモリ上に展開したものになる。プロトタイプベースではプロトタイプオブジェクトのクローンで生成されたオブジェクトを指す。実装レベルで言うとメモリ上に展開された中間参照ポインタの動的配列になる。
120 ⟶ 119行目:
:(''copy constructor'')は、メソッドの引数に対する値インスタンスの値渡しの時に呼び出されるコンストラクタである。値渡しはインスタンス内容全体のメモリコピーであり、基本データ型では特に問題は生じないが、そうでないクラスのインスタンスでは例えばあるリソースへの参照を保持している場合に好ましくない保持重複が発生する事になる。呼び出されたコピーコンストラクタは値インスタンスを受け取り、単純コピーが許されない部分に任意の処理を施して生成した値インスタンスのコピーを引数へと渡す。
;[[オーバーロード]]
:(''overloading'')は、一つのメソッド名に
;メソッド拡張
:(''method extension'')は、クラス定義とは別の場所でそのクラスに対する追加メソッドを定義できる機能である。これは状況に合わせてデータ抽象の表現に幅を持たせることを目的にしている。これには数々の書式があるが代表的なのは、静的メソッドまたは静的関数の第1引数をthis修飾して、その第1引数のクラス(型)に対してその静的メソッドをインスタンスメソッドとして追加するというものである。静的メソッドはそのクラススコープ内の限定拡張にできる。静的関数はネスト関数にしてそのローカルスコープ内の限定拡張にできる。双方はグローバル用途にすることもできる。アドホック多相とされる。
129 ⟶ 128行目:
;[[仮想継承]]
:(''virtual inheritance'')は、多重継承での[[菱形継承問題]]を回避するための仕組みである。菱形継承問題とは共にAクラスを親とするBクラスとCクラスの双方を継承した場合に、その継承構造上でAクラスが二つ重なって存在することになる不具合である。仮想継承では専用のテーブルが用意されて、そこでクラス名が参照アドレスにマッピングされる。BクラスからのAクラスと、CクラスからのAクラスは共に同じ参照アドレスをマッピングするのでAクラスはひとつにまとめられる事になる。同時に一度辿ったクラスは省略される事にもなる。
;メソッド解決順序
:(''
;[[抽象クラス]]
:(''abstract class'')は、クラスメンバの一部のメソッドだけが抽象化されているクラスを意味する。抽象化されたメソッドとは、メソッドシグネチャ(返り値+メソッド名+引数欄)だけが定義されてコード内容が省略されているメソッドを意味する。抽象クラスはインスタンス化できないので継承専用になる。抽象メソッドは、サブクラスの方でメソッドのコード内容が実装されてオーバーライドされる。
;[[インタフェース (抽象型)|インターフェース]]
:(''interface'')はプログラム概念と機能名の双方を指す用語である。言語によってはプロトコルと言われる。抽象メソッドと実メソッドをメンバにできる純粋抽象〜半抽象クラスを意味する。クラスの振る舞い側面を抜き出した抽象体である。クラスによるインターフェースの継承は実装と呼ばれる。多重実装可が普通である。ミックスインとの違いは、抽象階層に焦点が当てられている事であり、直下の実装オブジェクトを共通の振る舞い側面でまとめることがその役割である。インターフェースは自身の[[下位概念]]である実装継承オブジェクトをグループ化できる。{{仮リンク|記名的型付け|en|Nominal type system|label=}}に準拠しているのでインターフェースの実装の明記が振る舞い側面の識別基準になる。インターフェースは抽象メソッド主体なので多重継承時のメンバ名の重複はあまり問題にならない。共通の実装メソッドに集約されるからである。インターフェースは非インスタンス対象である。
;[[ミックスイン]]
:(''mixin'')はインターフェースに似たプログラム概念を指す用語である。機能名は言語によって[[トレイト]]、プロトコル、構造型(''structural type'')と言われる。抽象メソッドと実メソッドとデータメンバをメンバにできる継承専用クラスを意味する。クラスを特徴付けるための構成パーツである。クラスによるトレイトの継承は実装と呼ばれる。多重実装可が普通である。インターフェースとの違いは、トレイトの実装階層に焦点が当てられている事であり、オブジェクトを所有メンバで特定してまとめることがその役割である。トレイトは自身の[[上位集合]]である実装継承オブジェクトをグループ化できる。{{仮リンク|構造的型付け|en|Structural type system|label=}}に準拠しているので所属メンバ構成自体がトレイト等価性の識別基準になる。これはトレイト実装を明記していなくても、そのトレイトが内包する全メンバを所持していれば同じトレイトと見なされることを意味する。トレイトは合成や交差が可能である。トレイトは多重継承時のメンバ名重複の際にその参照の優先順位に注意する必要がある。トレイトは非インスタンス対象である。
;型イントロスペクション
:''(type introspection'')は一般に実行時型チェックと呼ばれるものである。プログラマが認知できない形でコンパイラまたはインタプリタが別途実装しているインスタンスの型情報を、実行時にその都度参照してインスタンスの型を判別する仕組みである。静的型付け下では専用の実行時型チェック構文(instanceofやdynamic_cast)によって型判別し、ダウンキャストなどに繋げられる。動的型付け下では変数への再代入時や関数への引数適用時にランタイムシステムが自動的に型判別し、多重ディスパッチなどに繋げられる。型イントロスペクションでは型情報のタグ識別子が判定基準になっているので{{仮リンク|記名的型付け|en|Nominal type system|label=}}の考え方に準じている。
;[[ダックタイピング]]
:''(duck typing'')は、特定の
;[[型推論]]
:オブジェクト指向下の型推論''(type inference'')は、型宣言ないし型注釈を省略して定義された変数の「型」が自動的に導き出される機能を指す。型はクラスと同義である。静的型付けの機能であり、コンパイラまたはインタプリタがソースコードをあらかじめ解析し
;[[メタクラス]]
:(''metaclass'')とはクラス自体の定義情報であり、そのクラスが持つとされるデータメンバ、メソッド、スーパークラス、内部クラスなどの定義が記録されたいわゆる[[メタデータ]]である。実装レベルでは、システム側が用意している特別なシングルトンオブジェクトと考えた方が分かりやすい。メタクラスの各種定義情報を参照または変更する機能はリフレクションと呼ばれる。メタクラスの変更はその対象クラスに直ちに反映される。クラスベースで用いられるものである。
148 ⟶ 149行目:
:(''metadata annotation'')はクラスに任意の情報を埋め込める機能である。情報とは文字列と数値からなるキーワード、シンボル、テキストである。プログラマが自由な形式で書き込んで随時読み取るものであるが、システムから認識される形式のものもある。実装レベルではメタクラスに書き込まれてリフレクション機能またはその[[糖衣構文]]で読み取ることになる。[[マーカーインタフェース|マーカーインターフェース]]の拡張とも見なされている。メタアノテーションはクラス単位だけでなく、言語によってはインスタンス単位やメソッド単位でも埋め込むことができる。アドホック多相とされる。
;動的ディスパッチ
:(''dynamic dispatch'')は、コンパイル時のメソッド名から呼び出されるメソッド内容が実行時に決定される仕組み全般を指す用語である。メソッドに引数を渡しての呼び出しを、オブジェクトにメッセージを発送(ディスパッチ)することになぞらえた事が由来である。発送先は実行時に選択決定されるメソッド内容を指す。メッセージは「[[This (プログラミング)|this参照]]×第1引数×第2引数..」といった[[直積集合]]で考えられているのでシングル、
;[[動的束縛|動的バインディング]]
:(''dynamic binding'')は、識別子が参照するまたは呼び出すオブジェクト、インスタンス、メソッド、データメンバなどのプログラム要素が、コンパイル時ではなく実行時に決められる仕組み全般を指す用語である。識別子はいわゆる変数名や関数名などを指す。
;遅延バインディング
:(''late binding'')は、識別子が参照するオブジェクトをコンパイル時に決める事前バインディング(''early binding'')の対義語であり、この場合は識別子が参照するオブジェクトを実行時に決める動的バインディングと同じ意味で用いられる。また他方では動的バインディングの中で、特に実行コードの動的ローディング機能を通して実装される方を遅延バインディングとする考え方もある。実行コードとは[[ダイナミックリンクライブラリ|DLL]]やクラスライブラリやモジュールなどを指しており、それらが内包するクラスやメソッドを専用の不透明型または動的束縛型に代入する。その呼び出しのための内部識別子はコンパイル時には存在していないことが多いので、実行時の文字列(char配列やString)を内部識別子に解釈するためのリフレクション機能が多用されることになる。
;[[パッケージ (Java)|パッケージ]]
173 ⟶ 174行目:
:(''abstract type member'')はジェネリッククラスのメンバ要素であり、ジェネリッククラス同士で型変数の内容をやり取りするための仲介要素である。Aクラスコンストラクタの型引数にBクラスを適用した際に、適切な代入定義が併記されたAクラス内のタイプメンバに、Bクラスがその内部で扱っている総称型もセットで適用できる。連想配列さながらにBクラスがキー的存在になってAクラスのタイプメンバ内容も決定されることから、この仕組みは関連型(''associated type'')と呼ばれる。
;[[関数オブジェクト]]
:オブジェクト指向下の関数オブジェクト(''function object'')は、メソッドそのものをオブジェクトして扱うというプログラム概念である。関数型プログラミングの[[クロージャ]]をモデルにしている。
;[[コルーチン]]
:オブジェクト指向下の[[イテレータ]]、[[ジェネレータ (プログラミング)|ジェネレータ]]、デコレータは、コルーチン(''coroutine'')機構に基づいている。通常のサブルーチンがコールする側の復帰アドレスだけをスタックに積むのに対して、コルーチンはコールする側とコールされる側双方の復帰アドレスをスタックに積むというサブルーチン機構である。各要素への作用が記されたオペレータが[[無名関数]]やラムダ式などの形態で[[コンテナ (データ型)|データコンテナ]]に渡されると、各要素をフェッチするデータコンテナと、フェッチされた要素を参照ないし加工するオペレータが交互に[[コールスタック]]を用いて連携動作を繰り返す。イテレータはオペレータをそのまま扱う機能である。ジェネレータはオペレータが反復処理を終えた後にその総和値や選別リストを生成する機能である。デコレータはメソッドをデータコンテナと見なしそのメソッド内での関数コールをそれぞれ要素にして、オペレータがフェッチされた関数名と引数欄を見ながら任意の処理を挿入する機能である。
187 ⟶ 188行目:
:転送(''forwarding'')。委譲先のクラスのメソッドが処理を行わずに、そのまた他のクラスの同名メソッドに引数をそのまま渡して、その返り値をそのまま呼び出し元に渡している場合、冒頭の委譲は転送になる。転送用メソッドではどのクラスに引数をパスするかという選択が行われるので、デリゲーションの多相を表現できる。
;[[Is-a|Is-a関係]]
:(''Is-a'')は[[上位概念、下位概念、同位概念および同一概念|上位概念と下位概念]]のコンセプトを扱っており、下位概念is-a上位概念となる。オブジェクト指向ではクラスの継承関係および実装継承関係を意味する用語になっている。これには汎化・特化・実現・実装の四種がある。
:* 汎化(''generalization'')は
:* 特化(''specialization'')は
:* 実現(''realization'')は、クラスからインターフェースへの連結を指す。
:* 実装(''
;[[Has-a|Has-a関係]]
:(''Has-a'')は[[部分集合|上位集合と部分集合]]のコンセプトを扱っており、上位集合has-a部分集合となる。オブジェクト指向ではクラスの構成関係を意味する用語になっている。これには合成・集約・収容・依存の四種がある。なお、依存(''dependency'')はhas-a関係における依存とそれ以外のクラス間関係における依存の意味が異なる二つが存在する。
:* 合成(''composition'')は強いhas-a関係であり、AクラスがBクラスをデータメンバにし、Aクラスのコンストラクタと同時にBインスタンスが生成され、Aクラスのデストラクタと同時にBインスタンスが破棄される場合、AはBの合成となる。Bが自身のサブクラスで交換される場合は分離とともに破棄される。
:* 集約(''
:* 収容(''containment'')は弱いhas-a関係であり、集約と同じであるが、Aクラスがコレクション(配列、List、Set、Map)の仕組みでBインスタンスを持つ場合のみを指している。コレクション関係を強調する場合、AはBを収容しているとなる。
:* 依存(''
;[[SOLID|SOLID原則]]
:(''SOLID Principles'')は、
:* (S){{仮リンク|単一責任原則|en|Single-responsibility principle}}は、クラス
:* (O)[[開放/閉鎖原則|解放閉鎖原則]]は、クラスを抽象クラス
:* (L)[[リスコフの置換原則]]は
:* (I){{仮リンク|インターフェース
:* (D)[[依存性逆転の原則|依存
; [[デザインパターン (ソフトウェア)|GOFデザインパターン]]
216 ⟶ 213行目:
: 生成に関するパターン<gallery heights="40">
ファイル:Abstract Factory UML class diagram.svg|[[Abstract Factory パターン|Abstract factory]]
ファイル:Factory Method UML class diagram.svg|[[Factory Method パターン|Factory Method]]▼
ファイル:Builder UML class diagram.svg|[[Builder パターン|Builder]]
▲ファイル:Factory Method UML class diagram.svg|[[Factory Method パターン|Factory Method]]
ファイル:Prototype UML.svg|[[Prototype パターン|Prototype]]
ファイル:Singleton UML class diagram.svg|[[Singleton パターン|Singleton]]
</gallery>
: 構造に関するパターン<gallery heights="40">
|