「オブジェクト指向プログラミング」の版間の差分
削除された内容 追加された内容
用語と解説 |
|||
(同じ利用者による、間の16版が非表示) | |||
19行目:
=== カプセル化 ===
一定の関連性を持つデータ(変数、プロパティ、フィールド、属性)と、それらを操作するメソッド(関数)をひとまとめにしてオブジェクトとし、外部に対して必要とされるデータとメソッドのみを公開し、それ以外を内部に隠蔽する仕組みがカプセル化と呼ばれる。公開されたデータは外部のメソッドから直接参照
=== 継承 ===
既存オブジェクトのデータ構成とメソッド構成を引き継いで、新しい派生オブジェクトを定義する仕組みが継承と呼ばれる。引き継ぐ際には新たなデータとメソッドを自由に追加できるので、派生オブジェクトの構成は既存
=== 多態性 ===
異なる種類のオブジェクトに同一の操作インターフェースを持たせる仕組みが多態性と呼ばれる。オブジェクト指向
=== メッセージパッシング ===
37行目:
=== 構造化プログラミングの提唱(1969 - 75) ===
[[Simula]]の普及と前後して1960年代半ばになると、プログラム規模の際限ない肥大化に伴う開発現場の負担増大が顕著になり、いわゆる[[ソフトウェア危機]]問題が計算機科学分野全般で取り沙汰されるようになった。その解決に取り組んだ計算機科学者[[エドガー・ダイクストラ]]は、1969年のNATOソフトウェア工学会議で「[[構造化プログラミング]]」という論文を発表し[[トップダウン設計とボトムアップ設計|トップダウン設計]]、段階的な[[抽象化 (計算機科学)|抽象化]]、階層的な[[モジュール化]]、共同詳細化(抽象データ構造と抽象ステートメントのjoint)といった構造化手法を提唱した。ダイクストラの言う構造化とは開発効率を高めるための[[分割統治法]]を意味していた。なおこの構造化プログラミングは後に曲解されて[[制御構造|制御構造文]]を中心にした解釈の方で世間に広まり定着している。共同詳細化は抽象データ構造を専用
<br>([[Sketchpad]]、[[Simula]]、[[アーパネット]]、[[バロース B5000|バロースB5000]]、それと専攻していた生物学と数学に影響されて僕はプログラミングアーキテクチャを思索していた)|Alan Kay}}1974年に[[MIT]]の計算機科学者[[バーバラ・リスコフ]]とステファン・ジルは「[[抽象データ型]]」というプログラム概念を提唱した。彼女らの理論は、ダイクストラが提示したモジュールの共同詳細化を、その振る舞いによって[[セマンティクス|
=== Smalltalkとオブジェクト指向の誕生(1972 - 81) ===
<br>(Smalltalkはその構文やライブラリやクラスをも関心にしていないという事だけではない。多くの人の関心を小さなアイディアに向かせたことから、僕はオブジェクトという用語を昔作り出したことを残念に思っている。大切なのはメッセージングなんだ。)|Alan Kay}}1980年のSmalltalk-80は、元々はメッセージを重視していたケイを自嘲させるほど同期的で双方向的で手続き的なオブジェクト指向へと変貌していた。それでも動的ディスパッチと[[委譲]]でオブジェクトを連携させるスタイルは画期的であり、1994年に発表される[[デザインパターン (ソフトウェア)|デザインパターン]]の模範にもされている。1981年に大手専門誌[[Byte (magazine)|BYTE Magazine]]がSmalltalkとケイ提唱のオブジェクト指向を紹介して世間の注目を集める契機になったが、ケイの思惑に反して技術的関心を集めたのはクラス機構の方であった。オブジェクト指向は知名度を得るのと同時に、Simula発の[[クラス (コンピュータ)|クラス]]とそれを理論面から形式化した[[抽象データ型]]を中心に解釈されるようになり、それらの考案者がケイの構想とは無関係であったことから、オブジェクト指向の定義はケイの手を離れて独り歩きするようになった。
=== C++の開発(1979 -
[[Simula]]を研究対象にしていた[[ベル研究所|AT&Tベル研究所]]の計算機科学者[[ビャーネ・ストロヴストルップ]]は、1979年からクラス付きC言語の開発に取り組み、1983年に「[[C++]]」を公開した。C++で実装された[[クラス (コンピュータ)|クラス]]は、Simula譲りの[[継承 (プログラミング)|継承]]と仮想関数に加えて、
<br />(僕はオブジェクト指向という言葉を作った、それとC++に関心がなかったことも分かっている)|Alan Kay}}1986年から[[Association for Computing Machinery|ACM]]
=== プロトタイプベースの考案(1985 - 90) ===
[[Smalltalk]]のオブジェクト指向は、[[アラン・ケイ]]がその影響を言及していた[[LISP]]コミュニティを逆に感化して、Smalltalkが
=== コンポーネントとネットワーク(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]]策定は、オブジェクト指向プログラミングの標準化を促進させた。
== 代表的なオブジェクト指向言語 ==
オブジェクト指向言語は、[[抽象データ型]]の仕組みに沿った[[クラスベース]]、
[[ファイル:History of object-oriented programming languages.svg|境界|中央|フレームなし]]
;[[Simula|Simula 67]] 1967年
59 ⟶ 62行目:
:[[メッセージパッシング]]のプログラム概念を導入した最初の言語。数値、真偽値、文字列から変数、コードブロック、メタデータまでのあらゆる要素をオブジェクトとするアイディアを編み出した最初の言語でもある。オブジェクト指向という言葉はSmalltalkの言語設計を説明する中で生み出された。オブジェクトにメッセージを送るという書式であらゆるプロセスを表現することが目標にされている。[[メッセージ転送|メッセージレシーバー]]と[[委譲]]の仕組みは、形式化されていない動的ディスパッチと[[ダイナミックバインディング|動的バインディング]]相当のものであり[[プロトタイプベース]]の源流にもなった。GUI運用環境に統合された専用のランタイム環境上で動作させる設計も模範にされ、これは後に[[仮想マシン]]や[[仮想実行システム]]と呼ばれるものになる。
;[[C++]] 1983年
:[[C言語]]に[[クラスベース]]のオブジェクト指向を追加したもの。Simulaの影響を受けている。[[静的型付け]]の[[クラス (コンピュータ)|クラス]]が備えられて
;[[Objective-C]] 1984年
:[[C言語]]に[[メッセージパッシング|メッセージ]]構文ベースのオブジェクト指向を追加したもの。こちらはSmalltalkの影響を受けており、それに準じた[[メッセージパッシング]]の書式が備えられた。メッセージを受け取るクラスの定義による[[静的型付け]]と共に、メッセージを[[委譲]]するオブジェクトの実行時決定による[[動的型付け]]も設けられている。オブジェクト指向的にはC++よりも正統と見なされた。[[制御構造|制御構造文]]が追加され、メッセージを送る書式も平易化されており、Smalltalkよりも扱いやすくなった。
65 ⟶ 68行目:
:[[Pascal]]にクラスベースのオブジェクト指向を追加したもの。当初はモジュールのデータ隠蔽的なカプセル化、単一継承、仮想関数による多態性という基本的なものだった。静的型付け重視である。[[多重定義|関数&演算子オーバーロード]](アドホック多相)と[[ジェネリックプログラミング|ジェネリクス]](パラメトリック多相)は当初採用に到らなかった。[[ニクラウス・ヴィルト|ヴィルト]]監修の[[アップル (企業)|アップル社]]による初回バージョンを基礎にして様々な企業団体による派生版が公開されており、その特徴と機能追加も様々である。
;[[Eiffel]] 1986年
:[[C++]]の柔軟性と融通性とは正反対のオブジェクト指向言語。[[クラスベース]]で[[静的型付け]]重視である。[[契約プログラミング|契約による設計]]
;[[Self]] 1987年
:[[メッセージパッシング|メッセージ]]構文ベースのオブジェクト指向言語。
;[[CLOS]] 1988年
:[[Common Lisp]]に[[プロトタイプベース]]に似たオブジェクト指向を追加したもの。[[構造体]]オブジェクトと[[多重定義|多重定義関数]]オブジェクトに分離されており、前者のスロットには任意のフィールドを、後者のスロットには任意のパラメータパターンを[[ダイナミックバインディング|動的バインディング]]できる動的型付け重視である。動的型付けの構造体オブジェクトを引数として渡される関数の[[多重ディスパッチ]]が重視されている。
;[[Python]] 1994年
:[[プロトタイプベース]]のオブジェクト指向スクリプト言語。[[基本データ型]]や[[コンテナ (データ型)|コレクション型]]などよく使われるデータ要素を全て組み込みのオブジェクトにしており、[[手続き型プログラミング]]スタイルでの関数の対象値としても扱いやすく、またコレクション型を扱うのに適した[[関数型プログラミング]]構文も導入されている。関数もオブジェクトなので柔軟に扱える。オブジェクトは自由にプロパティとメソッドを付け替えして様々に応用できるようデザインされている。オブジェクトは[[ダックタイピング]]で型判別されるので変数ないし関数の型宣言と型注釈は撤廃されている。ゆえに[[動的な型付け|動的型付け]]重視である。Pythonのプロトタイプオブジェクトはクラスと呼ばれている。多重継承可能であり親要素の参照順序はC3線形化で解決されている。アクセスコントロールはなくデータ抽象を軽視するコードスタイルと相まってカプセル化は備えられていない。多態性はメソッドの動的バインディングで行われる。後期バージョンで型ヒントが追加され、それに伴い[[ジェネリクス]]も導入された。
;[[Java]] 1995年
:[[C++]]をモデルにしつつ堅牢性とセキュリティを重視した[[クラスベース]]のオブジェクト指向言語。静的型付け重視である。パッケージ中心のカプセル化、単一のみの継承、仮想関数と多重実装可な[[インタフェース (抽象型)|インターフェース]]による多態性と、基本に忠実なクラスベースである。C++の[[
;[[Delphi]] 1995年
:[[Object Pascal]]を発展させたもの。それと同様にこちらも基本に忠実なクラスベースで静的型付け重視であった。当初はデータベース操作プログラム開発を主な用途にして公開された。クラスとレコード([[構造体]])に同等の比重が置かれていた。一時期Javaの対抗馬になった。
;[[Ruby]] 1995年
:[[Python]]を意識して開発されたオブジェクト指向スクリプト言語。[[Smalltalk]]を一つの理想にして動的型付けを重視している。日本で誕生してグローバル化したプログラミング言語である。[[LISP]]とSmalltalkのメタプログラミング的なオブジェクト指向から、Pythonと[[JavaScript]]のプロトタイプベースなオブジェクト指向までのスタイルを幅広く取り入れており、様々な有用なプログラミング手法を採用している技のデパートのような言語であ
;[[JavaScript]] 1996年
:[[
;[[C Sharp|C#]] 2000年
:[[Java]]を強く意識してマイクロソフト社が開発したクラスベースのオブジェクト指向言語。C++
;[[Scala]] 2003年
:[[クラスベース]]のオブジェクト指向と[[関数型プログラミング]]を融合させた言語。[[クラス (コンピュータ)|クラス]]機構と関数型の[[型システム]]に同等の比重が置かれており静的型付け重視である。[[ミックスイン]]相当の[[トレイト]]と[[ジェネリクス]]を連携させた多態性が重視されている。型変数の[[共変性と反変性 (計算機科学)|バリアンス]]、[[共変性と反変性 (計算機科学)|共変と反変]]双方の型境界、抽象
;[[Kotlin]] 2011年
:静的型付けの[[クラスベース]]のオブジェクト指向であるが、[[手続き型プログラミング]]に回帰しており、クラス枠外の関数とグローバル変数の存在感が高められている。クラスはpublicアクセスとfinal継承がデフォルトにされて、カプセル化と継承が公然と軽視されている。これによりインスタンスは手続き型の関数の対象値としての役割が強められ、その操作をサポートする関数型構文も導入されている。仮想関数と抽象クラスによる多態性は標準通りである。[[Java仮想マシン]]上で動作するJavaテクノロジ互換言語である。
;[[TypeScript]] 2012年
:[[JavaScript]]を強く意識してマイクロソフト社が開発したオブジェクト指向スクリプト言語。JavaScriptのプログラムを静的型付けで補完した言語である。[[クラスベース]]向けの構文と、[[関数型プログラミング]]の[[型システム]]のスタイルが加えられている。特に後者の性質が強調されている事から静的型付け重視である。継承構造によるサブタイプ多相はほぼ除外されており、パラメトリック多相とアドホック多相でオブジェクトを扱うという[[ジェネリクス]]と
;[[Swift (プログラミング言語)|Swift]] 2014年
:[[Objective-C]]を発展させたものであるが、メッセージ構文は破棄されており、クラスベースのオブジェクト指向になっている。オブジェクトの[[イミュータブル|イミュータブル性]]重視の構文
== 用語と解説 ==
;[[クラス (コンピュータ)|クラス]]
:クラス(''class'')の仕組みを中心にしたオブジェクト指向を[[クラスベース]]と言う。クラスはデータメンバとメソッドをまとめたものであり、[[プログラム意味論|
;プロトタイプオブジェクト
:プロトタイプ(''prototype'')の仕組みを中心にしたオブジェクト指向を[[プロトタイプベース]]と言う。プロトタイプベースで言われるオブジェクトとは、中間参照ポインタの動的配列を指す。この動的配列は一般にフレームと呼ばれる。中間参照ポインタは一般にスロットと呼ばれる。スロットにはデータメンバとメソッドの参照が代入されるので、オブジェクトはクラスと同様にデータメンバとメソッドをまとめたものになる。プロトタイプベースの実装形式は言語ごとに様々であるが基本は概ね以下のようになる。オブジェクトはプロトタイプオブジェクトとクローンオブジェクトに分かれる。前者はクラス、後者はインスタンスに当たるものである。前者はシステム提供プロトタイプとユーザー定義プロトタイプに分かれる。プログラマはシステム提供プロトタイプを派生させてユーザー定義プロトタイプを作成する。プロトタイプ
;[[メッセージ (コンピュータ)|メッセージ]]
:オブジェクト指向で言われるメッセージ(''message'')は、複数の方面の考え方が混同されている曖昧な用語になっている。元々はSmalltalkから始まったメッセージ構文ベースのオブジェクト指向の中心機構である。以前はクラスベースの方でもメソッドの呼び出しをメッセージを送るという風に考えることが推奨されていた。メッセージはオブジェクトのコミュニケーション手段と標榜されているが、その忠実な実装内容はそれほど知られていないのが実情である。最も混同されているものに[[アクターモデル]]があるが、そこで言われる非同期性とオブジェクト指向で言われる評価の遅延性は現行の実装スタイルではそれほど共通していない。コンポーネント準拠ソフトウェア工学と[[Object Request Broker|オブジェクトリクエストブローカー]]で言われる[[ソフトウェアコンポーネント]]同士の通信もメッセージパッシングと呼ばれることが多いが、その仕様と機能は動的ディスパッチに該当するものである。メッセージのオブジェクト指向的運用はメッセージングと名付けられている。具体的な機能例としてはSmalltalk、Objective-C、Selfの[[メッセージ転送|メッセージレシーバー]]と、Rubyのメソッドミッシングなどがあるが、いずれもメッセージングの本質ではないとも言われている。
;[[インスタンス]]
:(''instance'')はクラスベースではクラスを実体化(量化)したものであり、実装レベルで言うとデータメンバと仮想関数テーブルをメモリ上に展開したものになる。プロトタイプベースではプロトタイプオブジェクトのクローンで生成されたオブジェクトを指す。実装レベルで言うとメモリ上に展開された中間参照ポインタの動的配列になる。
;[[フィールド (計算機科学)|データメンバ]]
:(''data member'')はクラスまたはオブジェクトに属する変数。言語によってフィールド、プロパティ、メンバ変数、属性と呼ばれる。データメンバは、クラスデータメンバとインスタンスデータメンバに分かれる。クラスデータメンバは静的データメンバとも呼ばれる。その中で定数化されたものはクラス[[定数 (プログラミング)|定数]]と呼ばれる。クラスデータメンバはクラス名の名前空間でスコープされたグローバル変数と同じものであり、プログラム開始時から終了時まで確保される。インスタンスデータメンバはインスタンス生成時にメモリ上に確保されるものであり、その破棄時に消滅する。プロトタイプベースではプロトタイプオブジェクト
;[[メソッド (計算機科学)|メソッド]]
:(''method'')はクラスまたはオブジェクトに属する関数。言語によってはメンバ関数とも呼ばれる。データメンバの参照に特化したものはゲッター(''getter'')アクセッサ(''accessor'')と呼ばれる。データメンバの変更に特化したものはセッター(''setter'')ミューテイタ(''mutator'')と呼ばれる。メソッドは、クラスメソッドとインスタンスメソッドに分かれる。クラスメソッドは静的メソッドとも呼ばれる。クラスメソッドはクラス名の名前空間でスコープされたグローバル関数と同じものである。インスタンスメソッドを呼び出すには
;[[コンストラクタ]]
:(''constructor'')はインスタンス生成時に呼び出されるそのクラスのメソッドである。インスタンスデータメンバを任意の値で初期化するためのものであるが、その他の初期化コードも記述できる。プロトタイプベースではシステム提供プロトタイプ
;[[デストラクタ]]
:(''destructor'')はインスタンス破棄時に呼び出されるそのクラスのメソッドである。インスタンス破棄の影響を解決する任意の後始末コードを記述できる。インスタンスの破棄は占有メモリの解放を意味する。なお、ガーベジコレクタ実装言語ではファイナライザになっている事がある。プログラマが呼び出すデストラクタの方はその終了がメモリ解放に直結しているのに対し、ガーベジコレクタが呼び出すファイナライザの方はそうではない。
;[[This (プログラミング)|this参照]]
:(''this'')は、言語によっては「self」や「me」とも呼ばれる。インスタンスメソッドを呼び出す時は、このthis参照が暗黙の引数として渡されている。this参照はその該当インスタンスを指すポインタである。そのメソッド内でデータメンバにアクセスする時は、システム内で「this.データメンバ」のように変換されている。データにメソッドを付属させるカプセル化を実現するための仕組みである。
;super参照
:(''super'')は、継承構造のインスタンスメソッド内で用いられるものであり、現行クラスの直上スーパークラスのメソッドとデータメンバにアクセスするための参照である。オーバーライドやドミナンスを無視して、スーパクラスのメンバを呼び出すための仕組みである。
;アクセスコントロール
:(''access control'')は、カプセル化の情報隠蔽に基づ
;コピーコンストラクタ
:(''copy constructor'')は、メソッドの引数に対する値インスタンスの値渡しの時に呼び出されるコンストラクタである。値渡しはインスタンス内容全体のメモリコピーであり、基本データ型では特に問題は生じないが、そうでないクラスのインスタンスでは例えばあるリソースへの参照を保持している場合に好ましくない保持重複が発生する事になる。呼び出されたコピーコンストラクタは値インスタンスを受け取り、単純コピーが許されない部分に任意の処理を施して生成した値インスタンスのコピーを引数へと渡す。
;[[オーバーロード]]
:(''overloading'')は一つのメソッド名に複数の異なるパラメータリスト(引数欄)を付けたものを列挙してメソッド名を多重定義すること。[[演算子]]もオーバーロード対象であり、[[単項演算子]]なら一つの引数の型、[[二項演算子]]なら二つの引数の型を多重定義することで演算対象の値の型ごとに計算内容をカスタマイズできる。任意数の引数の型を多重定義できる( )演算子は、[[クロージャ]]または[[関数オブジェクト]]の表現に用いられる。アドホック多相とされる。
;メソッド拡張
:(''method extension'')は、クラス定義とは別の場所でそのクラスに対する追加メソッドを定義できる機能である。これは状況に合わせてデータ抽象の表現に幅を持たせることを目的にしている。これには数々の書式があるが代表的なのは、静的メソッドまたは静的関数の第1引数をthis修飾して、その第1引数のクラス(型)に対してその静的メソッドをインスタンスメソッドとして追加するというものである。静的メソッドはそのクラススコープ内の限定拡張にできる。静的関数はネスト関数にしてそのローカルスコープ内の限定拡張にできる。双方はグローバル用途にすることもできる。アドホック多相とされる。
;[[オーバーライド]]
:(''method overriding'')とは継承による階層的クラス構造のインスタンスにおいて、サブクラスのメソッドシグネチャの処理内容でそのスーパークラス側の同じメソッドシグネチャの処理内容を置き換える仕組みを指す。メソッドシグネチャとは「返り値+メソッド名+引数欄」で構成される識別単位である。この指定は親側のメソッドが上書きされるのをデフォルトにするのと、子側のメソッドで上書きするのをデフォルトにする二通りがある。前者なら子側のメソッドを''override''や''redefine''で修飾しそれで親側メソッドを上書きする。後者なら親側のメソッドを''virtual''や''deferred''や''abstract''で修飾しそれは子側メソッドで上書きされる。それとは別にただメソッドを上書き不可にする場合は''final''などで修飾する。オーバーライドはメソッド名を参照アドレスにマッピングする[[仮想関数テーブル]]と呼ばれる機能を用いて実現される。
;ドミナンス
:(''dominance'')は言語によってハイディング(''hiding'')マスキング(''masking'')とも呼ばれる。継承による階層的クラス構造において、サブクラスのメンバがスーパークラスの同名のメンバを隠していることを指す。親クラスのAメソッドを子クラスが同名Aメソッドでドミナンスした場合、子の型で参照してるインスタンスはそこでAのサーチが止まって子Aが呼び出される。ただし親の型で参照すれば親Aを呼び出せる。オーバーライドと異なり、参照する型でインスタンスの振る舞いを変えるための単純な仕組みでもある。
;[[仮想継承]]
:(''virtual inheritance'')は、多重継承での[[菱形継承問題]]を回避するための仕組みである。菱形継承問題とは共にAクラスを親とするBクラスとCクラスの双方を継承した場合に、その継承構造上でAクラスが二つ重なって存在することになる不具合である。仮想継承では専用のテーブルが用意されて、そこでクラス名が参照アドレスにマッピングされる。BクラスからのAクラスと、CクラスからのAクラスは共に同じ参照アドレスをマッピングするのでAクラスはひとつにまとめられる事になる。同時に一度辿ったクラスは省略される事にもなる。
;C3線形化
:(''C3 linearization'')は、多重継承で用いられる幅優先のメソッド解決順序(''Method Resolution Order'')である。メソッドはクラスメンバと読み替えてもよい。自クラス内に無いメンバを探すための親クラスの順序を決定する仕組みである。一般の多重継承では、深さ優先検索によるメソッド解決順序が用いられて親クラスの重複は仮想継承で解決される。それに対してC3線形化では、深さレベルを先行基準にした親クラスの整列と重複した親クラスのマージが行われて、その結果の親クラス線形化リストは幅優先検索になる。
;[[抽象クラス]]
:(''abstract class'')は、クラスメンバの一部のメソッドだけが抽象化されているクラスを意味する。抽象化されたメソッドとは、メソッドシグネチャ(返り値+メソッド名+引数欄)だけが定義されてコード内容が省略されているメソッドを意味する。抽象クラスはインスタンス化できないので継承専用になる。抽象メソッドは、サブクラスの方でメソッドのコード内容が実装されてオーバーライドされる。
;[[インタフェース (抽象型)|インターフェース]]
:(''interface'')はプログラム概念と機能名の双方を指す用語である。言語によってはプロトコルと言われる。抽象メソッドと
;[[ミックスイン]]
:(''mixin'')はインターフェースに似たプログラム概念を指す用語である。機能名は言語によって[[トレイト]]
;[[ダックタイピング]]
:''(duck typing'')は、特定のデータメンバ名またはメソッド名(メソッドシグ
;[[型推論]]
:オブジェクト指向下の型推論''(type inference'')は、型宣言ないし型注釈を省略して定義された変数の「型」が自動的に導き出される機能を指す。型はクラスと同義である。静的型付けの機能であり、ソースコードを解析しながら値の代入を始めとしたその変数の扱われ方によって型を導き出す。ここで導き出される「型」とは他の変数への代入可能性や、関数の引数への適用可能性といったあくまで等価性の基準で決められるので、プログラマが人為的な意味付けによる型定義を重視している場合は予期せぬ結果が発生することにもなる。
;[[メタクラス]]
:(''metaclass'')とはクラス
;[[リフレクション (情報工学)|リフレクション]]
:(''reflection'')は、メタクラスの定義情報を参照または変更する機能であるが、言語ごとに変更できる定義情報の範囲は異なっている。データメンバではデータ型、識別子、可視性が変更対象になる。メソッドではリターン型、識別子、パラメータリスト、可視性、仮想指定が変更対象になる。双方の追加定義と削除もできる事がある。スーパークラスも変更できる事がある。また、実行時の文字列(char配列やString)をデータメンバとメソッドの内部識別子として解釈できる機能もリフレクションに当たる。これは実行時の文字列によるデータメンバの参照とメソッドの呼び出しを可能にする。
;[[アノテーション|メタアノテーション]]
:(''metadata annotation'')はクラスに任意の情報を埋め込める機能である。情報とは文字列と数値からなるキーワード、シンボル、テキストである。プログラマが自由な形式で書き込んで随時読み取るものであるが、システムから認識される形式のものもある。実装レベルではメタクラスに書き込まれてリフレクション機能またはその[[糖衣構文]]で読み取ることになる。[[マーカーインタフェース|マーカーインターフェース]]の拡張とも見なされている。メタアノテーションはクラス単位だけでなく、言語によってはインスタンス単位やメソッド単位でも埋め込むことができる。アドホック多相とされる。
;動的ディスパッチ
:(''dynamic dispatch'')は、コンパイル時のメソッド名から呼び出されるメソッド内容が実行時に決定される仕組み全般を指す用語である。メソッドに引数を渡しての呼び出しを、オブジェクトにメッセージを発送(ディスパッチ)することになぞらえた事が由来である。発送先は実行時に選択決定されるメソッド内容を指す。メッセージは「this参照×第1引数×第2引数..」といった[[直積集合]]で考えられているのでシングル、[[ダブルディスパッチ|ダブル]]、[[多重ディスパッチ|マルチプル]]といった呼称になっている。発送先はthisおよび各引数の派生関係の組み合わせで選択される。thisの派生関係のみ影響しているのは仮想関数なシングルディスパッチである。それがthisでなく引数ならばただのシングルになる。thisと各引数の2個以上の派生関係が影響しているのはダブルないしマルチプルディスパッチになる。
;[[動的束縛|動的バインディング]]
:(''dynamic binding'')は
;遅延バインディング
:(''late binding'')は、識別子が参照するオブジェクトをコンパイル時に決める事前バインディング(''early binding'')の対義語であり、この場合は識別子が参照するオブジェクトを実行時に決める動的バインディングと同じ意味で用いられる。また動的バインディングの中で、特に実行コードの動的ローディング機能を通して実装される方を遅延バインディングとする考え方もある。実行コードとは[[ダイナミックリンクライブラリ|DLL]]やクラスライブラリやモジュールなどを指しており、それらが内包するクラスやメソッドを専用の
;[[
:(''package'')は1個以上のクラスをまとめたものである。多くなったクラスをグループ化するための仕組みである。パッケージの定義は言語ごとに異なるが、[[名前空間]](''namespace'')と同等の機能になっているケースが多い。実装レベルではパッケージ名は自動的にクラス名の接頭辞になってクラス名を差別化し、名前衝突を回避している。
;[[モジュール]]
:(''module'')は1個以上のクラスをまとめたものである。パッケージと似ているが、オブジェクト指向下のモジュールはもっぱら動的ローディング(遅延バインディング)と情報隠蔽に焦点を当てたプログラム概念である。情報隠蔽は[[カプセル化]]と同様に、自身の内包クラスの外部公開(輸出)と内部隠蔽を定義できる。自身が参照する他モジュールは輸入するという形式で明確に宣言される。動的ローディング用途のモジュールでは内包する基底クラスの詳細を明らかにしつつも、その派生クラスの種類と詳細を明らかにしていないケースが多々あるので、その派生クラスを代入するための動的束縛型は特に不透明型(''opaque type'')と呼ばれる。不透明型はもっぱら型制約と併せて用いられる。
;[[モンキーパッチ]]
:(''monkey patch'')はモジュールやスクリプトファイルなどの動的ローディングを用いて、インタプリタ実行後またはコンパイル後のソースコード内容を変化させる手法である。ソースコードに特定のフィルター処理を記述しておき、その中で任意の箇所を動的ローディングされたモジュール内のクラスや関数や変数で置き換えさせる事で、その時の配置モジュールに合わせた処理内容の変化ができる。モジュールを外せばフィルター処理は無効になる。この置き換え(パッチ当て)は遅延バインディング相当である。ソースコードを変えなくてよいのが条件である。
;[[ジェネリクス]]
:(''generics'')は、クラス内のデータメンバの型
;[[テンプレート (プログラミング)|テンプレート]]
:(''template'')は型変数のバリアンスを用いない方のジェネリクスを指す。コンパイル時に
;[[共変性と反変性 (計算機科学)|バリアンス]]
:(''variance'')は、ある
;型制約
:(''type constraint'')は、ジェネリッククラスの型引数ないし型変数、
;タイプメンバ
:(''abstract type member'')はジェネリッククラスのメンバ要素であり、ジェネリッククラス同士で型変数の内容をやり取りするための仲介要素である。Aクラスコンストラクタの型引数にBクラスを適用した際に、適切な代入定義が併記されたAクラス内のタイプメンバに、Bクラスがその内部で扱っている総称型もセットで適用できる。連想配列さながらにBクラスがキー的存在になってAクラスのタイプメンバ内容も決定されることから、この仕組みは関連型(''associated type'')と呼ばれる。
;[[関数オブジェクト]]
:オブジェクト指向下の関数オブジェクト(''function object'')は、メソッドそのものをオブジェクトして扱うというプログラム概念である。関数型プログラミングの[[クロージャ]]をモデルにしている。単にインスタンスを関数名らしく見せるための糖衣構文である( )[[演算子オーバーロード]]や、メソッドシグネチャを型種にした[[関数ポインタ]]型の変数である[[デリゲート (プログラミング)|デリゲート]]などの実装形式がある。デリゲート変数にはインスタンスメソッドへの参照が代入されてクラス種類とそのインスタンス種類による処理の多相を表現できる。プロトタイプベースにおける関数はオブジェクトそのものと言える存在であり、ローカル変数がプロパティ存在になっているのでクロージャが自然表現できる他、引数構成もプロパティ存在になっている場合はそれも変更できてクラスベースにおけるリフレクションを自然表現する。
;
:オブジェクト指向下の[[イテレータ]]、[[ジェネレータ (プログラミング)|ジェネレータ]]、デコレータは、コルーチン(''coroutine'')機構に基づいている。通常のサブルーチンがコールする側の復帰アドレスだけをスタックに積むのに対して、コルーチンはコールする側とコールされる側双方の復帰アドレスをスタックに積むというサブルーチン機構である。各要素への作用が記されたオペレータが[[無名関数]]やラムダ式などの形態で[[コンテナ (データ型)|データコンテナ]]に渡されると、各要素をフェッチするデータコンテナと、フェッチされた要素を参照ないし加工するオペレータが交互に[[コールスタック]]を用いて連携動作を繰り返す。イテレータはオペレータをそのまま扱う機能である。ジェネレータはオペレータが反復処理を終えた後にその総和値や選別リストを生成する機能である。デコレータはメソッドをデータコンテナと見なしそのメソッド内での関数コールをそれぞれ要素にして、オペレータがフェッチされた関数名と引数欄を見ながら任意の処理を挿入する機能である。
;[[メッセージ転送|メッセージレシーバー]]
:(''message receiver'')はメッセージを受け取ることに特化されたメソッドである。メッセージレシーバーはインスタンスのデフォルトで呼び出される窓口レシーバーの形態と、指定メソッドが存在していない時に呼び出される補足レシーバーの形態がある。窓口レシーバーのメッセージはセレクタと引数のペアまたはそのどちらかだけという書式である。窓口レシーバーは極めて柔軟なプロセスを実現できるが、実装の煩雑さとオーバーヘッドが大きくなる。セレクタは識別子またはペア引数の注釈になる文字列である。セレクタはメソッドへの自動分岐が主な用途になるが、そのフィルター処理と取りこぼし処理の中でただのキーワードとしても自由に解釈できる。補足レシーバーのメッセージはメソッド名文字列と引数配列という書式になっており、いかなるメソッドシグネチャにも該当しなかった取りこぼしになる。このメソッド名文字列と引数配列を自由に解釈して柔軟な処理を行える。補足レシーバーの機能名はメソッドミッシングなどである。
;[[派生型|サブタイピング]]
:(''subtyping'')はクラス(型)のあらゆる派生関係および派生構造の実装形式とその働き方を包括したプログラム概念である。サブタイプ多相(''subtype polymorphism'')とも呼ばれる。継承、オーバーライド、コンポジション、ジェネリクス、共変バリアンス、引数バリアンスによるディスパッチ、不透明型といったものは全てサブタイピングの一側面である。オブジェクト指向でよく使われるものは振る舞いサブタイピング(''behavioral subtyping'')であり、これに当てはまるものは継承とメソッドのオーバーライドを組み合わせた仮想関数である。
;[[委譲|デリゲーション]]
:委譲(''delegation'')
;フォワーディング
:転送(''forwarding'')。委譲先のクラスのメソッドが処理を行わずに、そのまた他のクラスの同名メソッドに引数をそのまま渡して、その返り値をそのまま呼び出し元に渡している場合、冒頭の委譲は転送になる。転送用メソッドではどのクラスに引数をパスするかという選択が行われるので、デリゲーションの多相を表現できる。
;汎化
:(''generalization'')は継承による[[is-a]]関係であり、サブクラスからスーパークラスへの連結を指す。
;特化
:(''specialization'')は継承による[[is-a]]関係であり、スーパークラスからサブクラスへの連結を指す。
;実現
:(''realization'')はクラスの振る舞いの抽象化による[[is-a]]関係であり、クラスからインターフェースへの連結を指す。振る舞いとは特定の目的に沿ったメソッド群である。
;実装
:(''implementation'')はクラスの振る舞いの抽象化による[[is-a]]関係であり、インターフェースからクラスへの連結を指す。振る舞いとは特定の目的に沿ったメソッド群である。
;合成
:(''composition'')は強い[[has-a]]関係。AクラスがBクラスをデータメンバにし、Aのコンストラクタと同時にBインスタンスが生成され、Aのデストラクタと同時にBインスタンスが破棄される場合、AはBの合成となる。Bが自身のサブクラスで交換される場合は分離とともに破棄される。
;集約
:(''aggregation'')は弱い[[has-a]]関係。AクラスがBクラスをデータメンバにし、Aクラスのコンストラクタとは関係なくBインスタンスが生成され、AクラスのデストラクタでBインスタンスが破棄されず、また分離時も破棄されない場合、AはBの集約となる。Aクラスがコレクション(配列、List、Set、Map)の仕組みでBインスタンスを持つ場合も、AはBの集約となる。コレクション性を強調する場合は収容(''containment'')とすることもある。
;関連
:(''association'')。AクラスがBクラスのメソッドを呼び出す場合、AはBに関連しているとなる。AはBへの誘導可能性を持つとされる(A→B)。has-a関係で保有しているインスタンスのメソッドを呼び出すという意味で関連線は合成線または集約線と重ねて引かれることが多い。
;依存
:(''dependency'')。AクラスのメソッドがBクラスのインスタンスを引数または返り値にしている場合、AはBに依存しているとなる。返り値の例として、Aのメソッドがその返り値としてBインスタンスを生成する場合も、AはBに依存しているとなる。
;SOLID
:(''SOLID Principles'')は、汎化・特化・実現・実装・関連・依存の連結線に焦点を当てたクラスの設計原則である。(S)単一責任原則・(O)解放閉鎖原則・(L)リスコフの置換原則・(I)インターフェース分離原則・(D)依存の逆向き原則といった五つから成り立っている。1974年にバーバラ・リスコフが提唱した(L)と、1988年にバートランド・メイヤーが提唱した(O)に、ロバート・マーティンが(S)(I)(D)を加えて2000年に発表されている。これはSOLIDの文字通りの順に解釈できるようになっている。
:(S)単一責任原則は、クラス(属性・操作)はただ一つの機能を表現するようにデザインすることを推奨している。(O)解放閉鎖原則は、クラスを抽象クラス(汎化・実現)と実装クラス(特化・実装)に分けてデザインすることを推奨している。(L)リスコフの置換原則は、汎化と特化に対する枠組みであり、実装クラスはその抽象クラスに対して振る舞い(=仮想関数)的に等価計算が可能であることを推奨している。(I)インターフェース分離原則は、実現と実装に対する枠組みであり、一つの抽象クラスは互いにその動作内容に影響し合うメソッドたちのみで構成されることを推奨している。(D)依存の逆向き原則は、関連と依存に対する枠組みであり、AクラスからBクラスに向けて関連線を引きたい場合は、Bクラスからその抽象クラスをAクラスに向けて実現し、その抽象クラスに対してAクラスからの関連線を引くことを推奨している。Bクラスとその抽象クラスを結ぶ依存線が、Aクラスからの関連線と逆向きになることがその名の由来である。
; GOFデザインパターン
: 生成に関するパターン<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]]
ファイル:Prototype UML.svg|[[Prototype パターン|Prototype]]
ファイル:Singleton UML class diagram.svg|[[Singleton パターン|Singleton]]
</gallery>
: 構造に関するパターン<gallery heights="40">
ファイル:Adapter pattern UML diagram.PNG|[[Adapter パターン|Adapter]]
ファイル:Bridge UML class diagram.svg|[[Bridge パターン|Bridge]]
ファイル:Composite UML class diagram (fixed).svg|[[Composite パターン|Composite]]
ファイル:Decorator UML class diagram.svg|[[Decorator パターン|Decorator]]
ファイル:Facade UML class diagram.svg|[[Facade パターン|Facade]]
ファイル:Flyweight UML class diagram.svg|[[Flyweight パターン|Flyweight]]
ファイル:UML DP Proxy.png|[[Proxy パターン|Proxy]]
</gallery>
: 振る舞いに関するパターン<gallery heights="40" perrow="11">
ファイル:Chain of responsibility UML diagram.png|[[Chain of Responsibility パターン|Chain of Responsibility]]
ファイル:Command Design Pattern Class Diagram.png|[[Command パターン|Command]]
ファイル:InterpreterUMLDiagramm.png|[[Interpreter パターン|Interpreter]]
ファイル:Iterator UML class diagram.svg|[[Iterator パターン|Iterator]]
ファイル:Mediator design pattern.png|[[Mediator パターン|Mediator]]
ファイル:Memento design pattern.png|[[Memento パターン|Memento]]
ファイル:Observer UML smal.png|[[Observer パターン|Observer]]
ファイル:State Design Pattern UML Class Diagram.svg|[[State パターン|State]]
ファイル:StrategyPattern.png|[[Strategy パターン|Strategy]]
ファイル:Template Method UML class diagram.svg|[[Template Method パターン|Template Method]]
ファイル:Visitor UML class diagram.svg|[[Visitor パターン|Visitor]]
</gallery>
== 脚注 ==
|