「オブジェクト指向」の版間の差分
Goldensundown2 (会話 | 投稿記録) カプセル化継承多態性はfundamental principleなので原則としました。OOはこうあるべきと示す規定だからです。原則に基づいて仕様が定められ必要な要素と各機能が作られます。あと、オブジェクト生成の種類は記述の少ない現状であえて特筆すべき主要項目でもないと思うので外しました。 |
|||
(同じ利用者による、間の2版が非表示) | |||
5行目: | 5行目: | ||
}} |
}} |
||
'''オブジェクト指向'''(オブジェクトしこう、{{lang-en-short| |
'''オブジェクト指向'''(オブジェクトしこう、{{lang-en-short|''object-oriented''}})は、[[ソフトウェア工学]]理論の一つであり、ソフトウェア設計とプログラム記述の際に用いられる考え方である。 |
||
元々は[[プログラミングパラダイム|プログラミング・パラダイム]]用に考案された漠然的な構想であり、1967年に公開されたプログラミング言語「[[Simula|Simula 67]]」が持つ[[クラス (コンピュータ)|クラス]]仕様が一つの発端とされる<ref>[http://kristennygaard.org/FORSKNINGSDOK_MAPPE/F_OO_start.html How Object-Oriented Programming Started]</ref><ref>{{Cite web|url=http://www.olejohandahl.info/old/birth-of-oo.pdf|title=The Birth of Object Orientation: the Simula Languages|author=Ole-Johan Dahl|date=June 2001|accessdate=2019-02-02}}</ref><ref>[http://staff.um.edu.mt/jskl1/talk.html INTRODUCTION TO SIMULA]</ref><ref>{{Cite web|url=https://www.cs.cmu.edu/~charlie/courses/15-214/2014-fall/slides/25-history-oo.pdf|title=OO History: Simula and Smalltalk|author=Jonathan Aldrich and Charlie Garrod|date=2014|accessdate=2019-02-02}}</ref>。他方で「[[LISP]]」の影響を受けたという<ref>"Dr. Alan Kay on the Meaning of Object-Oriented Programming". 2003. Retrieved 11 February 2010.</ref>計算機科学者[[アラン・ケイ]]が、1972年から「[[Smalltalk]]」の開発を進める中でオブジェクト指向という言葉を初めて定義した。彼によるとオブジェクトとは占有記憶(データ)とそれを操る動作(コード)を持ち、メッセージを相互に送受して任意の処理を実現し、上述の[[クラス (コンピュータ)|クラス]]から生成されるとされた。この[[オブジェクト (プログラミング)|オブジェクト]]を中心にしてシステムを組み立てる考え方がオブジェクト指向という事になる。また「[[Simula|Simula 67]]」の影響を受けた[[ビャーネ・ストロヴストルップ]]が1983年に公開した「[[C++]]」が契機となり、オブジェクト指向を規定する為の三大原則([[カプセル化]]、[[継承 (プログラミング)|継承]]、[[多態性]])が提唱された。 |
|||
オブジェクト指向はその後[[データベース]]や[[オペレーティングシステム|OS]]の設計・開発などにも活かされるようになり、1990年代になるとソフトウェア工学の幅広い面にも応用されて、オブジェクト指向を土台にした様々な分野が開拓された。 |
|||
==起源== |
==起源== |
||
32行目: | 30行目: | ||
{{Main|オブジェクト指向プログラミング}} |
{{Main|オブジェクト指向プログラミング}} |
||
⚫ | |||
=== 主な要素 === |
|||
以下は[[ビャーネ・ストロヴストルップ]]が提唱した[[C++]]系統のオブジェクト指向における三大要素<!-- 原則ではなく要素。 -->である。[[Simula]]由来の[[クラス (コンピュータ)|クラス]]機構を根幹とする。のちに[[クラスベース]]オブジェクト指向の欠点を克服するために[[プロトタイプベース]]オブジェクト指向も考案されたが、基本的な方向性に大きな差異はない。 |
以下は[[ビャーネ・ストロヴストルップ]]が提唱した[[C++]]系統のオブジェクト指向における三大要素<!-- 原則ではなく要素。 -->である。[[Simula]]由来の[[クラス (コンピュータ)|クラス]]機構を根幹とする。のちに[[クラスベース]]オブジェクト指向の欠点を克服するために[[プロトタイプベース]]オブジェクト指向も考案されたが、基本的な方向性に大きな差異はない。 |
||
38行目: | 36行目: | ||
* [[カプセル化]] (encapsulation) |
* [[カプセル化]] (encapsulation) |
||
⚫ | |||
: [[オブジェクト (プログラミング)|オブジェクト]]のデータと、データに関連する振る舞い(操作、[[サブルーチン|関数]]あるいは[[メソッド (計算機科学)|メソッド]])をひとまとめにすること、またそれらに対して外部からのアクセスを制御・限定すること<ref>[http://e-words.jp/w/%E3%82%AB%E3%83%97%E3%82%BB%E3%83%AB%E5%8C%96.html カプセル化とは - IT用語辞典]</ref>。 |
|||
⚫ | |||
* [[継承 (プログラミング)|継承]] (inheritance) |
* [[継承 (プログラミング)|継承]] (inheritance) |
||
49行目: | 46行目: | ||
: 通例、実行時の型(動的な型)に応じて呼び出されるコードが決定される「動的な多態性」のことを指す<ref>C++では同じ[[シグネチャ]]を持つ仮想関数(仮想メソッド)の[[オーバーライド]]により動的な多態性を利用できるが、内部的には通例[[仮想関数テーブル]]による動的ディスパッチを用いて実現されている。仮想メソッドのオーバーライドでは1変数に関する動的ディスパッチしかできないが、2変数以上に関する動的ディスパッチ([[多重ディスパッチ]])の仕組みをサポートする言語もある。</ref>。 |
: 通例、実行時の型(動的な型)に応じて呼び出されるコードが決定される「動的な多態性」のことを指す<ref>C++では同じ[[シグネチャ]]を持つ仮想関数(仮想メソッド)の[[オーバーライド]]により動的な多態性を利用できるが、内部的には通例[[仮想関数テーブル]]による動的ディスパッチを用いて実現されている。仮想メソッドのオーバーライドでは1変数に関する動的ディスパッチしかできないが、2変数以上に関する動的ディスパッチ([[多重ディスパッチ]])の仕組みをサポートする言語もある。</ref>。 |
||
: [[静的型付け]]言語において、メソッドの実引数として渡すオブジェクトの型に従って、呼び出されるメソッドが選択される[[多重定義]](オーバーロード)<ref>[[被演算子]]を演算子関数の引数とみなし、ユーザー定義の演算子オーバーロードをサポートする言語もある。言語組み込みの演算子も被演算子の型に応じてコードが変化するため、これも演算子オーバーロードの一種である。</ref>や、[[ジェネリックプログラミング]]において、型引数に応じて生成されるコードが変化する{{仮リンク|パラメータ多相|en|Parametric polymorphism}}なども多態性の一種と見なされる。これらは「静的な多態性」に分類され、実行時ではなくコンパイル時に動作が決まる。 |
: [[静的型付け]]言語において、メソッドの実引数として渡すオブジェクトの型に従って、呼び出されるメソッドが選択される[[多重定義]](オーバーロード)<ref>[[被演算子]]を演算子関数の引数とみなし、ユーザー定義の演算子オーバーロードをサポートする言語もある。言語組み込みの演算子も被演算子の型に応じてコードが変化するため、これも演算子オーバーロードの一種である。</ref>や、[[ジェネリックプログラミング]]において、型引数に応じて生成されるコードが変化する{{仮リンク|パラメータ多相|en|Parametric polymorphism}}なども多態性の一種と見なされる。これらは「静的な多態性」に分類され、実行時ではなくコンパイル時に動作が決まる。 |
||
⚫ | |||
* [[クラスベース]] |
|||
: まずオブジェクトの設計図となる任意の[[クラス (コンピュータ)|クラス]]を定義し、そのクラスを元に[[インスタンス]]を生成する方式である。 |
|||
* [[プロトタイプベース]] |
|||
: プログラム実行環境に用意されている[[インスタンス]]をプロトタイプとしてクローンし、任意のプロパティやメソッドを追加して拡張していく方式である。インスタンスベースとも言われる。 |
|||
* [[ミックスイン]] |
|||
: 任意のインスタンス生成時に、実行環境に用意された様々な機能コンポーネントを追加する方式である。各コンポーネントは同時にスーパークラスと同等となり、手軽で重複の無い多重継承が保証された。 |
|||
=== オブジェクト指向とメッセージング === |
=== オブジェクト指向とメッセージング === |
2019年2月20日 (水) 06:47時点における版
オブジェクト指向(オブジェクトしこう、英: object-oriented)は、ソフトウェア工学理論の一つであり、ソフトウェア設計とプログラム記述の際に用いられる考え方である。
元々はプログラミング・パラダイム用に考案された漠然的な構想であり、1967年に公開されたプログラミング言語「Simula 67」が持つクラス仕様が一つの発端とされる[1][2][3][4]。他方で「LISP」の影響を受けたという[5]計算機科学者アラン・ケイが、1972年から「Smalltalk」の開発を進める中でオブジェクト指向という言葉を初めて定義した。彼によるとオブジェクトとは占有記憶(データ)とそれを操る動作(コード)を持ち、メッセージを相互に送受して任意の処理を実現し、上述のクラスから生成されるとされた。このオブジェクトを中心にしてシステムを組み立てる考え方がオブジェクト指向という事になる。また「Simula 67」の影響を受けたビャーネ・ストロヴストルップが1983年に公開した「C++」が契機となり、オブジェクト指向を規定する為の三大原則(カプセル化、継承、多態性)が提唱された。
起源
オブジェクト指向の起源自体は明確ではない。また、突発的に生まれたものでもなく、例えば以下に挙げるような様々な概念や技術が発展・融合して生まれたものである[6][7]。
- 哲学(モナドなど)、言語哲学(記号論など)、認知科学
- 人工知能に関する研究
- データモデル(E-Rモデルおよび意味データモデル)
- ソフトウエア工学の基本概念(モジュール、情報隠蔽、型理論)
- コンピュータ・アーキテクチャ(OS、GUI、デバイス)
オブジェクト指向の分野
- オブジェクト指向プログラミング (1960年代から)
- オブジェクトデータベース (1980年代から)
- オブジェクト指向分析設計 (1990年代から)
- オブジェクト指向モデリング (1990年代から)
オブジェクト指向は、プログラミング・パラダイムとして誕生した知識体系である。そのデータとコードのセットを基本要素にして物事を解析する考え方が、特に1980年代から大きく注目され始め、ソフトウェア工学のあらゆる局面にobject-oriented (OO) を接頭辞にした分野が立ち上げられた。他にも、OOオペレーティングシステム、OOプロジェクトマネージメント、OOソフトウェアエンジニアリング、OOユーザーインターフェース、ブーチメソッド、オブジェクトモデリングテクニックなど複数の分野が存在するが、上記リストの四種と知識範囲が重なり合っているか、または内包される副次分野となっていることから、明確な一つの分野として扱われることは少ない。
オブジェクト指向プログラミング
オブジェクト指向に基づいたプログラミングスタイルのことであり、Object-Oriented Programmingの頭文字をとってOOPと略されることもある。
オブジェクト指向の三大原則
以下はビャーネ・ストロヴストルップが提唱したC++系統のオブジェクト指向における三大要素である。Simula由来のクラス機構を根幹とする。のちにクラスベースオブジェクト指向の欠点を克服するためにプロトタイプベースオブジェクト指向も考案されたが、基本的な方向性に大きな差異はない。
なお、アラン・ケイが提唱したSmalltalk系統のオブジェクト指向は、以下とは別の異なる概念を根幹としている(後述)。
- カプセル化 (encapsulation)
- 継承 (inheritance)
- 派生元オブジェクトに任意のデータとメソッドを追加する形で派生先オブジェクトを作る方式(部品→全体)と、オブジェクトを複数の階層に分解して他オブジェクトと共有できる階層を派生元にする方式(全体→部品)の二通りの考え方がある[要出典]。継承によりデータ構造およびコードの再利用と拡張を可能にする。
- クラスベースのオブジェクト指向では、派生元オブジェクトのデータ型はスーパークラスあるいは基底クラスなど、派生先オブジェクトのデータ型はサブクラスあるいは派生クラスなどと呼ばれる。派生クラスのインスタンスはまた基底クラスのインスタンスとしても扱えるようになる(リスコフの置換原則)。継承により、後述の多態性を実現することができるようになる。
- 多態性 (polymorphism)
- 任意のメソッドの呼び出し時に、メソッドが属する実際のオブジェクトの種類(クラス)によって呼び出し先の実装コードが選択され、処理内容が変化する性質。
- 通例、実行時の型(動的な型)に応じて呼び出されるコードが決定される「動的な多態性」のことを指す[9]。
- 静的型付け言語において、メソッドの実引数として渡すオブジェクトの型に従って、呼び出されるメソッドが選択される多重定義(オーバーロード)[10]や、ジェネリックプログラミングにおいて、型引数に応じて生成されるコードが変化するパラメータ多相なども多態性の一種と見なされる。これらは「静的な多態性」に分類され、実行時ではなくコンパイル時に動作が決まる。
オブジェクト指向とメッセージング
オブジェクト指向プログラミングは、歴史的にSimulaのオブジェクトおよびクラスの概念を発端とするが、Simulaの理念を直接的に受け継いだC++系統と、1970年代から研究開発が進められていたメッセージ・パッシングの仕組みを主体とするSmalltalk系統に大別されており、理想的なオブジェクト指向本来の形態を正しく表現しているのは後者のSmalltalk系統のほうだと評されていた。しかし、20世紀後半当時の計算機資源(CPU処理能力やメモリ容量など)の問題や、理論より実務上の利便性を重視する開発現場の事情から、より簡便な設計および少ないリソース下でもオブジェクト指向プログラミングのための機能を「クラス機構」を活かして実現できるC++系統のほうが主流となった。
Smalltalk系統のオブジェクト指向の主要概念であるメッセージパッシング (message passing) は、従来のサブルーチンコールの形態を変えたものであり、基本はバイトデータの送受信でメソッド名とパラメータ値およびリターン値をやり取りするという仕組みだった。このバイトデータの羅列が「メッセージ」と呼ばれ、大抵は先頭の伝言名と後続の引数名&引数値の配列で構成された。オブジェクトのレシーバー関数が引数として渡されたメッセージを読み込み、オブジェクト内部でそれに準じた処理を行い、結果をリターンした。レシーバーの仕組みは結果的に「カプセル化」を実現できた。オブジェクト内部での自由自在な処理実装によるリターンはこれも結果的に「多態性」を実現できた。この多態性が示す多重ディスパッチないし動的ディスパッチを円滑に実装するために、クラス構造定義を自由に操作できる「リフレクション」の機能が備えられた。
なお、Smalltalk開発者の一人であり、オブジェクト指向開発環境のパイオニアと見なされているアラン・ケイは「オブジェクト指向という用語を作り出したのは自分だが、これは悪い選択だった。なぜならば、メッセージ送信のもっと重要なアイディアを十分強調していない。」というコメントを残している[11][12]。
上述の通り、Smalltalkが主体とするメッセージングは堅牢なカプセル化と高度に柔軟な多態性を自然に表現できる仕組みだった。それに対して、C++やJavaに見られる「クラス機構」と継承をベースにした同様の機能の実現はトリッキーと言えた。しかし、実際には「クラス機構」重視の、言わば亜流のほうがオブジェクト指向の主流となってしまった。アラン・ケイは「自分自身もSmalltalkの大ファンではない。とはいえ、今日のたいていのプログラミングシステムに比べれば好ましいものだが。」とも述べている。
脚注
- ^ How Object-Oriented Programming Started
- ^ Ole-Johan Dahl (June 2001). “The Birth of Object Orientation: the Simula Languages”. 2019年2月2日閲覧。
- ^ INTRODUCTION TO SIMULA
- ^ Jonathan Aldrich and Charlie Garrod (2014年). “OO History: Simula and Smalltalk”. 2019年2月2日閲覧。
- ^ "Dr. Alan Kay on the Meaning of Object-Oriented Programming". 2003. Retrieved 11 February 2010.
- ^ Part2 オブジェクト指向の発展の歴史 | 日経 xTECH(クロステック)
- ^ オブジェクト指向(おぶじぇくとしこう) - ITmedia エンタープライズ
- ^ C++ではどのコード領域からもアクセス可能なpublic、自クラスと派生クラスからのみアクセス可能なprotected、自クラス内でのみアクセス可能なprivate、の三種を規定しており、C++の派生言語では類似のアクセス修飾子をサポートしていることが多い。
- ^ C++では同じシグネチャを持つ仮想関数(仮想メソッド)のオーバーライドにより動的な多態性を利用できるが、内部的には通例仮想関数テーブルによる動的ディスパッチを用いて実現されている。仮想メソッドのオーバーライドでは1変数に関する動的ディスパッチしかできないが、2変数以上に関する動的ディスパッチ(多重ディスパッチ)の仕組みをサポートする言語もある。
- ^ 被演算子を演算子関数の引数とみなし、ユーザー定義の演算子オーバーロードをサポートする言語もある。言語組み込みの演算子も被演算子の型に応じてコードが変化するため、これも演算子オーバーロードの一種である。
- ^ オブジェクト指向プログラミングは間違いだったか? - InfoQ
- ^ Object Oriented Programming: The Wrong Path? - InfoQ
関連項目
- 構造化プログラミング
- アスペクト指向
- エージェント指向
- ソフトウェア工学
- デザインパターン (ソフトウェア)
- Category:オブジェクト指向言語
- オブジェクト指向プログラミング
- オブジェクトデータベース
- オブジェクト関係データベース
- オブジェクト指向モデリング
- オブジェクト指向分析設計
- オブジェクト指向ソフトウェア工学
- NEXTSTEP - オブジェクト指向OSとしてその先進性をアピール。後続OSや開発環境に大きな影響を与えた。
- Cocoa - NEXTSTEPの後身のフレームワーク。