「オブジェクト指向」の版間の差分

削除された内容 追加された内容
編集の要約なし
編集の要約なし
1行目:
'''オブジェクト指向'''(オブジェクトしこう、{{lang-en-short|''object-oriented''}})は、[[ソフトウェア工学]]理論の一つであり、ソフトウェア設計とプログラム記述の際に用いられる考え方である。元々は特定の[[プログラミングパラダイム|プログラミング・パラダイム]]を説明する為に考案された言葉だった。''object-oriented programming''のように修飾語として用いられるのが常であり、それ単体で扱われる事はない漠然とした設計構想でもある。
{{複数の問題
|独自研究=2019年2月
|正確性=2019年2月
|出典の明記=2019年2月
}}
<!-- 「仕様」という言葉を安易に濫用するべきではない。仕様とは、満たすべき機能や性能を列挙したもの。機能や性能自体ではない。 -->
 
オブジェクト指向という言葉自体は、1972年にプログラミング言語「[[Smalltalk]]」を公開した計算機科学者[[アラン・ケイ]]が、その言語設計を説明する中で初めて生み出されている<ref name="EarlyHistoryOfSmalltalk">{{Cite web|url=http://worrydream.com/EarlyHistoryOfSmalltalk/|title=The Early History Of Smalltalk|author=Alan C. Kay|accessdate=2019-02-21}}</ref>。そこから遡って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>{{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 name="EarlyHistoryOfSmalltalk" />。その後、計算機科学者[[ビャーネ・ストロヴストルップ]]が1983年に公開した「[[C++]]」が契機となり、オブジェクト指向に関連する様々な考え方が再定義された。1980年代から[[データベース]]と[[オペレーティングシステム|OS]]の開発にも活かされるようになり、1990年代になるとソフトウェア工学の幅広い面にも応用されて、オブジェクト指向を土台にした様々な分野が開拓されるに到った。
'''オブジェクト指向'''(オブジェクトしこう、{{lang-en-short|object-orientation}}<ref>[https://eow.alc.co.jp/search?q=object+orientation object orientationの意味・使い方|英辞郎 on the WEB:アルク]</ref>)は、[[ソフトウェア工学]]構想の一つであり、ソフトウェア設計とプログラム記述の際に用いられる考え方あるいは概念(コンセプト)である。修飾語として用いられる{{lang|en|object-oriented}}は「オブジェクト指向の」という意味を持つ[[複合形容詞]]であり、修飾対象がオブジェクト指向に基づいていること、あるいはオブジェクト指向に関連することを意味する。
 
特に[[プログラミング (コンピュータ)|コンピュータプログラミング]]分野におけるオブジェクト指向のエッセンスおよびコンセプト自体は、もともと1962年に公開された[[Simula|Simula I]]と、その成功を受けて開発された[[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>。のちにSimulaの影響を強く受けた[[ビャーネ・ストロヴストルップ]]の[[C++]]と、Simulaのほかに[[LISP]]の影響を強く受けた[[アラン・ケイ]]の[[Smalltalk]]<ref name="EarlyHistoryOfSmalltalk">{{Cite web|url=http://worrydream.com/EarlyHistoryOfSmalltalk/|title=The Early History Of Smalltalk|author=Alan C. Kay|accessdate=2019-02-21}}</ref>によってオブジェクト指向が再定義された。
 
==起源==
オブジェクト指向の起源自体は明確ではない。また、突発的に生まれたものでもなく、例えば以下に挙げるような様々な概念や技術が発展・融合して生まれたものである<ref>[https://tech.nikkeibp.co.jp/it/article/lecture/20070710/277100/ Part2 オブジェクト指向の発展の歴史 | 日経 xTECH(クロステック)]</ref><ref>[https://www.itmedia.co.jp/im/articles/0909/29/news106.html オブジェクト指向(おぶじぇくとしこう) - ITmedia エンタープライズ]</ref>。
* 哲学([[モナド (哲学)|モナド]]など)、[[言語哲学]]([[記号論]]など)、[[認知科学]]
* [[人工知能]]に関する研究
* [[データモデル]]([[実体関連モデル|E-Rモデル]]および意味データモデル)
* ソフトウエア工学の基本概念(モジュール、情報隠蔽、型理論)
* コンピュータ・アーキテクチャ([[オペレーティングシステム|OS]]、[[グラフィカルユーザインタフェース|GUI]]、デバイス)
 
==オブジェクト指向の分野==
25 ⟶ 10行目:
* [[オブジェクト指向モデリング]] (1990年代から)
 
オブジェクト指向は、プログラミング・パラダイムとして誕生した知識体系である。そのデータとコードのセットを基本要素にして物事を解析する考え方が、特に1980年代から大きく注目され始めた事で、ソフトウェア工学のあらゆる局面に''object-oriented'' (OO) を接頭辞にした分野が立ち上げられた。他にも、OOオペレーティングシステム、OOプロジェクトマネージメント、[[オブジェクト指向ソフトウェア工学|OOソフトウェアエンジニアリング]]、OOユーザーインターフェース、[[Booch法|ブーチメソッド]]、[[オブジェクトモデル化技法|オブジェクトモデリングテクニック]]など複数の分野が存在するが、上記リストの四種と知識範囲が重なり合っているか、または内包される副次分野となっていることから、明確な一つの分野として扱われることは少ない
 
他にも、OOオペレーティングシステム、OOプロジェクトマネージメント、[[オブジェクト指向ソフトウェア工学|OOソフトウェアエンジニアリング]]、OOユーザーインターフェース、[[Booch法|ブーチメソッド]]、[[オブジェクトモデル化技法|オブジェクトモデリングテクニック]]など複数の分野が存在するが、上記リストの四種と知識範囲が重なり合っているか、または内包される副次分野となっていることから、明確な一つの分野として扱われることは少ない。
==オブジェクト指向プログラミング==
オブジェクト指向に基づいたプログラミングスタイルのことであり、{{lang|en|Object-Oriented Programming}}の頭文字をとってOOPと略されることもある。
{{Main|オブジェクト指向プログラミング}}
 
==オブジェクト指向プログラミングとは==
=== 主な要素 ===
オブジェクト指向(''object-oriented'')の言葉を生み出した計算機科学者[[アラン・ケイ]]は、1972年に公開した論文の中でその設計を六つの要約で説明している<ref name="EarlyHistoryOfSmalltalk" />。
以下は[[ビャーネ・ストロヴストルップ]]が提唱した[[C++]]系統のオブジェクト指向における三大要素<!-- 原則ではなく要素。 -->である。[[Simula]]由来の[[クラス (コンピュータ)|クラス]]機構を根幹とする。のちに[[クラスベース]]オブジェクト指向の欠点を克服するために[[プロトタイプベース]]オブジェクト指向も考案されたが、基本的な方向性に大きな差異はない。
 
#''EverythingIsAnObject.''
なお、[[アラン・ケイ]]が提唱した[[Smalltalk]]系統のオブジェクト指向は、以下とは別の異なる概念を根幹としている(後述)。
#''Objects communicate by sending and receiving messages (in terms of objects).''
 
#''Objects have their own memory (in terms of objects).''
* [[カプセル化]] (encapsulation)
#''Every object is an instance of a class (which must be an object).''
: [[オブジェクト (プログラミング)|オブジェクト]]のデータと、データに関連する振る舞い(操作、[[サブルーチン|関数]]あるいは[[メソッド (計算機科学)|メソッド]])をひとまとめにすること、またそれらに対して外部からのアクセスを制御・限定すること<ref>[http://e-words.jp/w/%E3%82%AB%E3%83%97%E3%82%BB%E3%83%AB%E5%8C%96.html カプセル化とは - IT用語辞典]</ref>。
#''The class holds the shared behavior for its instances (in the form of objects in a program list).''
: アクセス権限(可視性)の種別はプログラミング言語によって異なる<ref>C++ではどのコード領域からもアクセス可能な''public''、自クラスと派生クラスからのみアクセス可能な''protected''、自クラス内でのみアクセス可能な''private''、の三種を規定しており、C++の派生言語では類似の{{仮リンク|アクセス修飾子|en|Access modifiers}}をサポートしていることが多い。</ref>。
#''To eval a program list, control is passed to the first object and the remainder is treated as its message.''
 
* [[継承 (プログラミング)|継承]] (inheritance)
: {{要出典範囲|date=2019年2月|派生元オブジェクトに任意のデータとメソッドを追加する形で派生先オブジェクトを作る方式(部品→全体)と、オブジェクトを複数の階層に分解して他オブジェクトと共有できる階層を派生元にする方式(全体→部品)の二通りの考え方がある}}。継承によりデータ構造およびコードの再利用と拡張を可能にする。
: クラスベースのオブジェクト指向では、派生元オブジェクトのデータ型はスーパークラスあるいは基底クラスなど、派生先オブジェクトのデータ型はサブクラスあるいは派生クラスなどと呼ばれる。派生クラスのインスタンスはまた基底クラスのインスタンスとしても扱えるようになる([[リスコフの置換原則]])。継承により、後述の多態性を実現することができるようになる。
 
* [[多態性]] (polymorphism)
: 任意のメソッドの呼び出し時に、メソッドが属する実際のオブジェクトの種類(クラス)によって呼び出し先の実装コードが選択され、処理内容が変化する性質。
: 通例、実行時の型(動的な型)に応じて呼び出されるコードが決定される「動的な多態性」のことを指す<ref>C++では同じ[[シグネチャ]]を持つ仮想関数(仮想メソッド)の[[オーバーライド]]により動的な多態性を利用できるが、内部的には通例[[仮想関数テーブル]]による動的ディスパッチを用いて実現されている。仮想メソッドのオーバーライドでは1変数に関する動的ディスパッチしかできないが、2変数以上に関する動的ディスパッチ([[多重ディスパッチ]])の仕組みをサポートする言語もある。</ref>。
: [[静的型付け]]言語において、メソッドの実引数として渡すオブジェクトの型に従って、呼び出されるメソッドが選択される[[多重定義]](オーバーロード)<ref>[[被演算子]]を演算子関数の引数とみなし、ユーザー定義の演算子オーバーロードをサポートする言語もある。言語組み込みの演算子も被演算子の型に応じてコードが変化するため、これも演算子オーバーロードの一種である。</ref>や、[[ジェネリックプログラミング]]において、型引数に応じて生成されるコードが変化する{{仮リンク|パラメータ多相|en|Parametric polymorphism}}なども多態性の一種と見なされる。これらは「静的な多態性」に分類され、実行時ではなくコンパイル時に動作が決まる。
 
なお、ビャーネ・ストロヴストルップ自身は、広義の「オブジェクト指向」として、以下に列挙する要素をプログラミング言語または技法が直接的にサポートすることを要件として提案している<ref>{{Cite web|url=http://www.stroustrup.com/oopsla.pdf|title=Why C++ is not just an Object-Oriented Programming Language|author|Bjarne Stroustrup|accessdate=2019-02-21}}</ref>。これにはC++、Simula、Smalltalkなど多くの言語が含まれることになるが、[[C言語]]や[[Fortran]] 4、[[Pascal]]といった古典的な言語は除外される。
 
# 抽象化 (abstraction)
# 継承 (inheritance)
# 実行時の多態性 (run-time polymorphism)
 
=== オブジェクト指向とメッセージング ===
オブジェクト指向プログラミングは、歴史的に[[Simula]]のオブジェクトおよびクラスの概念を発端とするが、Simulaの理念を直接的に受け継いだ[[C++]]系統と、1970年代から研究開発が進められていた[[メッセージ (コンピュータ)|メッセージ・パッシング]]の仕組みを主体とする[[Smalltalk]]系統に大別されており、理想的なオブジェクト指向本来の形態を正しく表現しているのは後者のSmalltalk系統のほうだと評されていた。しかし、20世紀後半当時の計算機資源([[CPU]]処理能力やメモリ容量など)の問題や、理論より実務上の利便性を重視する開発現場の事情から、より簡便な設計および少ないリソース下でもオブジェクト指向プログラミングのための機能を「クラス機構」を活かして実現できるC++系統のほうが主流となった。
 
[[Smalltalk]]系統のオブジェクト指向の主要概念である'''[[メッセージパッシング]]''' (message passing) は、従来のサブルーチンコールの形態を変えたものであり、基本はバイトデータの送受信でメソッド名とパラメータ値およびリターン値をやり取りするという仕組みだった。このバイトデータの羅列が「[[メッセージ (コンピュータ)|メッセージ]]」と呼ばれ、大抵は先頭の伝言名と後続の引数名&引数値の配列で構成された。オブジェクトのレシーバー関数が引数として渡されたメッセージを読み込み、オブジェクト内部でそれに準じた処理を行い、結果をリターンした。レシーバーの仕組みは結果的に「[[カプセル化]]」を実現できた。オブジェクト内部での自由自在な処理実装によるリターンはこれも結果的に「[[多態性]]」を実現できた。この多態性が示す[[多重ディスパッチ]]ないし動的ディスパッチを円滑に実装するために、クラス構造定義を自由に操作できる「[[リフレクション (情報工学)|リフレクション]]」の機能が備えられた。
 
Smalltalkの構想は以下の6つのアイディアに体系化されている<ref name="EarlyHistoryOfSmalltalk"/>。
 
これをやや意訳するとこうなる。
# すべてはオブジェクトである。
# オブジェクトはメッセージの送受信によって通信相互作用する。
# オブジェクトは自身の記憶領域 (memory) (データ)を持つ。
# すべてのオブジェクトクラスのインスタンスであり、クラスもまたオブジェクトである。
# クラスはそのインスタンス群のための共有されたする振る舞い (behavior) (メソッド)を持つ。
# プログラムリストを評価するために実行時は、制御は最初のオブジェクトに渡され、残りはそのメッセージとして扱われる。
 
(1)はプログラム内のあらゆる要素をオブジェクトとして扱う事を示している。これがオブジェクト指向と名付けられた由縁である。(2)のメッセージ送受信とは、サブルーチン呼び出しとリターン値のやり取りに近いものであるが、より柔軟な視点から再解釈されている。(3)と(5)によってオブジェクトとは、データとメソッドの複合体である事が示されている。(4)によってオブジェクトの実装は、クラスという定義情報とそれを実メモリに展開したインスタンスで為される事が示されている。またクラスもオブジェクトとする事でいわゆるメタデータの扱いも可能にしている。
上記(6)はLISP風の普遍構文 (universal syntax) を暗示している。
 
この[[オブジェクト (プログラミング)|オブジェクト]]を中心にしてシステムを組み立てていく考え方がSmalltalkのオブジェクト指向である。
 
なお、Smalltalk開発者の一人であり、オブジェクト指向開発環境のパイオニアと見なされているアラン・ケイは「オブジェクト指向という用語を作り出したのは自分だが、これは悪い選択だった。なぜならば、メッセージ送信のもっと重要なアイディアを十分強調していない。」というコメントを残している<ref>[http://www.infoq.com/jp/news/2010/07/objects-smalltalk-erlang オブジェクト指向プログラミングは間違いだったか? - InfoQ]</ref><ref>[https://www.infoq.com/news/2010/07/objects-smalltalk-erlang Object Oriented Programming: The Wrong Path? - InfoQ]</ref>。
 
上述の通り、Smalltalkが主体とするメッセージングは堅牢なカプセル化と高度に柔軟な多態性を自然に表現できる仕組みだった。それに対して、C++や[[Java]]に見られる「クラス機構」と継承をベースにした同様の機能の実現はトリッキーと言えた。しかし、実際には「クラス機構」重視の、言わば亜流のほうがオブジェクト指向の主流となってしまった。アラン・ケイは「自分自身もSmalltalkの大ファンではない。とはいえ、今日のたいていのプログラミングシステムに比べれば好ましいものだが。」とも述べている。
 
==脚注==
81 ⟶ 38行目:
 
==関連項目==
*[[構造化プログラミング]]
*[[アスペクト指向]]
*[[エージェント指向]]
*[[ソフトウェア工学]]
*[[デザインパターン (ソフトウェア)]]
99 ⟶ 53行目:
*[[NEXTSTEP]] - オブジェクト指向OSとしてその先進性をアピール。後続OSや開発環境に大きな影響を与えた。
*[[Cocoa]] - NEXTSTEPの後身のフレームワーク。
* [[継承 (構造化プログラミング)|継承]] (inheritance)
*[[アスペクト指向]]
*[[エージェント指向]]
 
==外部リンク==