「オブジェクト指向プログラミング」の版間の差分

削除された内容 追加された内容
編集の要約なし
(同じ利用者による、間の4版が非表示)
9行目:
'''オブジェクト指向プログラミング'''(オブジェクトしこうプログラミング、{{Lang-en-short|object-oriented programming}}; OOP)は、[[オブジェクト指向]]の[[プログラミングパラダイム|考え方]]<ref>コンピュータ・プログラミングのパラダイムについては『新しいプログラミング・パラダイム』などを参照: http://www.kyoritsu-pub.co.jp/bookdetail/9784320024939</ref>を取り入れた[[プログラミング (コンピュータ)|コンピュータ・プログラミング]]技法である。プログラムを「[[オブジェクト (プログラミング)|オブジェクト]]」の集合体として構築し、オブジェクトはデータ(状態)を主とし、コード(動作)を従として構成され、無数のオブジェクトが相互に作用し合うようにして任意の処理が実行される。オブジェクトとは対象物を意味し、CPU演算処理(コード)が参照ないし変動の対象とするデータ全般と考える事が出来る。「どの様にデータを扱うか」ではなく「データがどの様に扱われるか」を念頭に置いてプログラムを組み立てる手法がOOPという事になる。
 
オブジェクト指向プログラミングは、ソフトウェアの大規模化に伴い、より効率的な開発手法が模索される中で1960年代から70年代にかけて確立された。OOP言語は歴史的にクラス機構仕様を中心とする[[Simula]]系統と、メッセージ機構仕様を主体とする[[Smalltalk]]系統に分けられるが、後に[[C++]]や[[Java]]などの言語の派生元となった前者が主流となった。この前者のオブジェクト指向が示す「[[カプセル化]]」「[[継承 (プログラミング)|継承]]」「[[ポリモーフィズム|多態性]]」の三大機能原則を備えていれば、OOP言語であると見なされる。
 
== 機能特徴 ==
OOPの基本原則(''fundamental principle'')仕様は以下の通りである。1~3は[[Simula]]系統であるクラス主体(''classes-principled'')OOPの三大原則となっている。4は[[Smalltalk]]系統であるメッセージ主体(''messaging-principled'')OOPの主要原則とされる。
OOP環境の主な機能は以下の通りである。
 
* #[[カプセル化]] (''encapsulation'') - <small>内部隠蔽</small>
* #[[継承 (プログラミング)|継承]] (''inheritance'')
* #[[ポリモーフィズム|多態性]] (''polymorphism'')
*#*[[多重定義]] (''overloading'') - <small>演算子オーバーローディングも含む</small>
*#*{{仮リンク|パラメータ多相|en|Parametric polymorphism}} (''parametric polymorphism'') - <small>[[ジェネリックプログラミング]]</small>
*#*[[派生型|派生型付け]] (''subtyping'') - <small>動的なもののみ</small>
*#*[[仮想関数]] (''virtual function'')
*#*[[多重ディスパッチ]] (''multiple dispatch'')
* #[[メッセージ (コンピュータ)|メッセージパッシング]] (''message passing'')
 
; カプセル化
 
従来の手続き型プログラミング環境では、「動作」を定義する'''コード'''が、「状態」を表現する'''データ'''を扱う形でプログラムを記述するのが一般的だったが、開発規模の拡大に伴い、解決の難しいソフトウェア・バグ原因の大半は「データの予期せぬ変動」と「各データ間の予期せぬ不整合」である事が経験則で知られるようになって来た。そこでデータを中心にしてプログラムを組み立てようとする考え方が生まれ、データ群とそれに付随するコード群をまとめた'''オブジェクト'''というプログラミング概念が編み出された。従来の「コードの為のデータ」とは逆に「データの為のコード」としたのは、データを変動させたコード位置を容易に特定出来るようにしてバグ発見に繋げる為であった。この目的に沿って特定のデータを扱えるコード範囲を厳密に定めた'''データ内部隠蔽'''の機能は、アクセス許可範囲からデータ参照とコード領域での利用呼出システムコンパイルレベルで禁止して、想定外のデータ変動をもたらす人的ミスを減らした。
 
; 継承
 
また、プログラム内の膨大な数のデータは通常グループ化(構造体)されて扱われていたが、各構造体間にまたがる共通のデータ集合が多数出現し、その冗長性と整合の頻雑さの問題が浮き彫りとなっていた。これを解決する為にOOPは、構造体=オブジェクトを複数の'''階層要素'''に分け、共通のデータ集合を親階層とし、派生する子階層に親階層の参照アドレスを持たせて連結する構造とした。A階層から成る親オブジェクトから派生した子オブジェクトはA+B階層として構成され、これが'''継承'''と呼ばれた。コードから参照されたデータがB階層に無い時は、次のA階層に有るか探す仕組みとなり、この連鎖によって傍からは一つのオブジェクトとして存在した。なお、派生クラスで任意のデータとメソッドを追加出来る継承の機能は、同時に工夫次第でコードの再利用性を高めるとも見なされたが、深い継承がもたらす構成把握の難化がネックとなってほぼ否定されるなり、クラスライブラリ使用の範疇内に留まている。{{いつ範囲|date=2019年2月|現在}}では深い継承は回避される様になり、代わりに共通メソッド呼出テーブル(Javaのinterfaceなど)を実装させる横に長い継承が主流となっている。また、Simula系統のOOP言語では多態性を実現する為の重要な手段として用いられている。
 
; 多態性
38行目:
; メッセージパッシング
 
上述の三つの機能と異なり、メッセージパッシングはオブジェクト指向そのものと肩を並べるパラダイムであり、オブジェクト指向が示す機能の大半を結果的に実現出来る「[[メタデータ|メタ]]」的な土台となった。これは従来のサブルーチンコールの形態を変えたもので、基本はバイトデータ('''メッセージ''')の送受信でメソッド名とパラメータ値およびリターン値をやり取りする仕組みだった。オブジェクトのレシーバー関数が引数として渡されたメッセージを読み込み、オブジェクト内部でそれに準じた処理を行い、結果をリターンした。レシーバーの仕組みは結果的に「情報内部隠蔽」を実現出来た。オブジェクト内部での自由自在な処理実装によるリターンはこれも結果的に「多態性」を実現出来た。この実装をサポートする為に「[[リフレクション (情報工学)|リフレクション]]」の機能が備えられた。メッセージパッシングがもたらす変幻自在なメソッドの選択実行は、通信網を介して他サーバー上で実行されているサービスプロセスを自身のソフトウェアの一部として扱う様な事も可能にした。あらゆる手法に応用出来るメッセージパッシングは、その適用範囲を広げるほど開発工数と実行負荷も増大するので、決してオールマイティに用いられるものではないが、ソフトウェアのモジュール化およびコンポーネント化をよりダイナミックに、そしてグローバルに発展させる潜在力を秘めており、OOPがもたらす実装の拡張性を大きく広げた。
 
== 歴史 ==
58行目:
 
== OOP言語一覧 ==
オブジェクト指向を総体的または部分的にサポートする機能を備えたプログラミング言語仕様の公開は、1980年代後半から顕著となった。オブジェクト指向プログラミングのスタイルは、[[クラス (コンピュータ)|クラス機構仕様]]を中心とする'''Simula系統'''と、[[メッセージパッシング|メッセージ機構仕様]]を主体とする'''Smalltalk系統'''の二通りに分けられる。前者には「C++」「Java」「C#」などが、後者には「Smalltalk」「Objective-C」「Swift」などが挙げられる。
 
オブジェクト指向プログラミング言語の形態には、オブジェクト指向と他の[[プログラミングパラダイム|パラダイム]]が同居している'''ハイブリッドOOP'''と、オブジェクト指向に基づくコードプロセスだけが許容される'''ピュアOOP'''の双方が存在する。前者には「C++」「Objective-C」「Java」「C#」「Swift」などが、後者には「Smalltalk」「Eiffel」「Self」などがある。言語仕様の中でオブジェクト指向の存在感が比較的高い代表的なプログラミング言語を以下に列挙する。
 
言語仕様の中でオブジェクト指向の存在感が比較的高い代表的なプログラミング言語を以下に列挙する。
<big>{{独自研究範囲|date=2019年2月|形成期(1967 - 1984)}}</big>
 
[[Simula|'''Simula 67''']] 1967年
: 1962年に公開された[[Simula]]の後継版であり、[[クラス (コンピュータ)|クラス機構仕様]]を導入した最初の言語。現実世界の擬似モデルを観測するシミュレーション・プログラム記述用に開発され、後に汎用化された。C++、Java、C#に代表される'''クラス主体OOP'''のルーツとされる。
 
'''[[Smalltalk]]''' 1980年
: オブジェクト間の相互作用を担う[[メッセージパッシング|メッセージ機構仕様]]を導入した最初の言語。オブジェクト指向という言葉は、Smalltalk開発者がその言語仕様を説明する中で生み出された。'''メッセージ主体OOP'''の元祖であり、高度に柔軟なオブジェクトの連携動作を表現できた。また、後に仮想マシンと呼ばれる専用のランタイム環境も用意された。
 
'''[[C++]]''' 1983年
: [[C言語]]にクラス主体OOPに基づく言語仕様を追加したもの。Simulaの影響を強く受けている。クラス機構仕様によってカプセル化、継承、多態性を表現している。また[[ジェネリックプログラミング|ジェネリクス]]に相当する[[テンプレート (プログラミング)|テンプレート機能]]も備えていた。元がC言語であるため、OOPから逸脱した[[手続き型プログラミコーディング]]も多用できる点が物議を醸したが、その是非はプログラマ次第であるという結論に落ち着いた。
 
'''[[Objective-C]]''' 1984年
:[[C言語]]にメッセージ主体OOPに基づく言語仕様を追加したもの。Smalltalkの影響を強く受けている。独自のメッセージ機構が特徴的である。OOP言語的には前述のC++よりも正統であると見なされた。他のプログラミング・パラダイムも共存しており、Smalltalkよりもコーディングし易くなった。
 
<big>{{独自研究範囲|date=2019年2月|派生期(1985 - 1994)}}</big>
 
[[Object Pascal|'''Object Pascal''']] 1986年
82 ⟶ 80行目:
 
'''[[Eiffel]]''' 1986年
:[[Pascal]]をベースにしてクラス主体OOPに基づく言語仕様と[[ジェネリックプログラミング|ジェネリクス]]のパラダイムを追加した。型付けは静的に限られ、単純な数値もオブジェクトとして扱えるようにし、非参照データを自動解放する[[ガーベジコレクション|ガーベジコレクタ]]を備え持ち、多重継承時の問題を回避する仕組みや、共有コード実行時のタイミング同一性を保証する例外処理など、より高い堅牢性を目指し備え仕様も盛り込まれている。これらは後のJavaやC#の手本となった。
 
'''[[Self]]''' 1987年
: クラスメッセージ主体OOPに分類される。従来の[[クラスベース]]に対して、システムが用意したオブジェクト複製(クローン)に機能追加して任意の拡張ることで拡張していく[[プロトタイプベース]]の概念初めて実装した。[[実行時コンパイラ]](just-in-time compiler)を備える専用のランタイム環境で実行された。{{要出典範囲|date=2019年2月|これは[[Java仮想マシン]]や[[.NET Framework]]の手本となった}}
 
'''[[CLOS]]''' 1988年
:[[Common Lisp]]にクラスメッセージ主体OOPに基づく言語仕様を追加したもの。
 
'''[[Python]]''' 1990年
: クラス主体OOPに分類される。[[インタプリタ]]式で動作する。言語仕様を簡素化し自動メモリ管理機能を実装して扱いやすく理解しやすいOOPを目指している。後のOOPスクリプト言語の手本となった。
 
'''[[Perl|Perl 5.0]]''' 1994年
 
: 従来の[[Perl]]に、クラス主体OOPに基づく簡便な言語仕様が追加された。
 
<big>{{独自研究範囲|date=2019年2月|発展期(1995 - 2004)}}</big>
 
'''[[Java]]''' 1995年
:堅牢性と安全性を重視したクラス主体OOPである。仮想マシン上の実行、ガーベジコレクタ、例外処理などを採用し、多重継承とジェネリックを破棄したがその埋め合わせの仕様も備えられている。メッセージ主体OOP的設計を表現出来るシリアライゼーションやリフレクションの仕様も導入された。非常に整えられたハイブリッドOOP言語である。
:C++から複雑な機能やあいまいな仕様を取り除き、簡素化したOOP言語。クラス機構主体である。
 
'''[[Delphi]]''' 1995年
:[[ボーンド]]ス主体OOPよって開発分類され。[[Object Pascal]]を発展させたもので、データベースの操作プログラム開発などを主な用途としているた。一時期Javaの対抗馬となった
 
[[Ada|'''Ada 95''']] 1995年
:[[Ada]]にクラス主体OOPに基づく言語仕様が追加された。
 
'''[[Ruby]]''' 1995年
: クラス主体OOPに分類されるスクリプト言語である。[[インタプリタ]]式で動作する。[[ソフトウェアコンポーネント]]による開発の効率化を目指した[[Mixin]]を特徴とする。スクリプトでありながら、クラス、マルチスレッド、例外処理など、そして[[ソフトウェアコンポーネント]](モジュール)を扱える[[Mixin]]といった利便性汎用性の高い機能も備えている。
 
'''[[JavaScript]]''' 1996年
:[[ウェブアプリケーション]]開発を主な目的とするOOPスクリプト言語。主に[[プロトタイプベース]]オブジェクト指向言語機能持ち、扱う事でコーディングを簡便にしている。クラス主体OOPに分類される。[[ECMAScript]]として標準化されている。ECMAScript 2015ではクラス構文をサポートするようになった。
 
[[PHP (プログラミング言語)|'''PHP 4''']] 2000年
: 従来の[[PHP (プログラミング言語)|PHP]]に、クラス主体OOPに基づく言語仕様が追加された。
[[C Sharp|'''C#''']] 2000年
:[[C++]]、[[Java]]、[[Delphi]]などに影響受け強く意識して開発されクラス主体OOP言語。[[.NET Framework]]などの[[共通言語基盤]]上で実行される。クラス機構主体であJavaと同等または部分的に拡張させた仕様を持ち、こちらもよく整えられたハイブリッドOOP言語として知られる。
[[Microsoft Visual Basic .NET|'''Visual Basic.NET''']] 2002年
: 従来の[[Microsoft Visual Basic|Visual Basic]]の構文をベースにしつつ、クラス主体OOPに基づいて言語仕様が改変されている。[[.NET Framework]]などの[[共通言語基盤]]上で実行される。
[[COBOL|'''COBOL 2002''']] 2002年
:[[COBOL]]にクラス主体OOPに基づく言語仕様が追加された。Object COBOLとも呼ばれる。
 
<big>{{独自研究範囲|date=2019年2月|最新系(2005年以降)}}</big>
 
'''[[Ceylon]]''' 2011年
129 ⟶ 113行目:
:[[Javaバイトコード]]を出力し、[[Java仮想マシン]]上で動作するJVM互換のOOP言語。関数型プログラミング言語由来の機能を持つ。
[[Swift (プログラミング言語)|'''Swift''']] 2014年
:[[Objective-C]]の後継言語。クラス主体OOPとメッセージ主体OOPの中間分類され位置する。関数型プログラミング言語由来の機能など他のパラダイムも併せっている
 
== OOP言語の仕組み ==
170 ⟶ 154行目:
もう一つは同一種類のオブジェクトでもそれぞれ異なる部分、典型的には各オブジェクトが保持するデータ群である。
 
==== インスタンスオブジェクトとクラスオブジェクト ====
動的型付けを採用するオブジェクト指向言語の多くは、クラスより生成するインスタンスの他に[[メタクラス]]という機能を持ちクラス自体をオブジェクトとして扱うことが出来る。このためオブジェクトには、インスタンスオブジェクトとクラスオブジェクトという2種類のオブジェクトが存在する。Java等クラスオブジェクトを持たない言語の文化圏では、インスタンスオブジェクトとオブジェクトを混同して説明される事があるが、Objective-CやPython、Ruby等、インスタンスオブジェクトとクラスオブジェクトが別であるオブジェクト指向言語では区別して説明される。<ref>Objective-Cプログラミ
ング言語[https://developer.apple.com/jp/devcenter/ios/library/documentation/ObjC.pdf]</ref>