コンテンツにスキップ

英文维基 | 中文维基 | 日文维基 | 草榴社区

利用者:I.hidekazu/クラス (プログラミング)

2つのプログラムが与えられたとき、それらを結合するには、単純に連接(concatenation)する方法と、疑似的にでも並列実行させてメッセージ渡しで結合させる方法がある。

プログラミングにおけるクラス: class)とは、ALGOL 60の拡張言語であるSIMULAにおいて、疑似並列処理を実現するために導入された構文を言う。当初は、「プロセス(process)」と呼ばれていた[1]

疑似的にでも並列処理を用いることができれば、結合させたい2つのプログラムをそれぞれ並列に走らせておいて、必要な処理をメッセージ渡しでやり取りすれば、正しく動作しているプログラムをほとんど崩すことなくそのまま使いまわすことができる。

クラスの構文は、ALGOL 60におけるブロック(block)を拡張したものである。ブロックが生成する計算プロセス(instance;インスタンス)は制御が戻ると消滅するのに対して、クラスが生成するインスタンスは制御が戻っても消滅せず存在し続ける[2]。ブロックは無限にインスタンスを生成できるが、これをインスタンスの集まり(class of instances)と同一視して、オーレ=ヨハン・ダールによってクラス(class)と命名された[3]。クラスのインスタンスは特にオブジェクト(object)と呼ばれる[4]

クラスの構文では、変数宣言と手続き宣言をまとめて行うことができる。クラスの本体に局所的に定義された変数、手続きなどはどれも、そのクラスの所属物(attribute)であると呼ばれ[5]、クラスのオブジェクト X の所属物 A に対しては、X.A という形で確認と変更ができる[6]。クラスを用いて抽象データ型を実現させることもできる。

当初、ボトムアップ式の構造化プログラミングの技法として提案された[7][9]。現代においてクラスは、オブジェクト指向プログラミングの基本となっている[10][11]

概要

[編集]
2つのプログラムを一つの計算プロセス上に単純に連接する場合、変数名の衝突、手続き名の衝突を避けるために調整しなくてはならない。さらにプログラムごとの動作の分岐など一つのプログラムとして動作させるために、元プログラムに大きく手を加えなくてはならなくなる。そのためバグ取りも大きくコストがかかり、プログラムの再利用性が低い。

1972年、オランダの計算機科学者のエドガー・ダイクストラはすぐれたプログラマがそれまで意識せずに用いてきていた方法の考え方を構造化プログラミング論(狭義の構造化プログラミング)としてまとめ、プログラムの大規模開発への道を開いたが、あくまで単一スレッド(single thread)計算機を前提としたトップダウン型開発方法であった。すなわち、プログラムのすべての機能は単線の計算プロセス上で実行する必要があり、たとえ甲と乙という汎用的な単機能を提供する検証済みのプログラムがそれぞれ独立に存在していても、両機能を実現するプログラムを作成するためには、ソースコードから該当機能部分を抜き出し、単線上に乗るように連接(concatenation)した上で、一つのプログラムとして正しく動作するように修正し、さらに再度検証しなければならない。

一方で、疑似的にでも複数スレッド(multi thread)を実現できる計算機においては、主プログラムから、甲と乙のプログラムなどの従プログラムをそれぞれ独立に実行させた上で、処理内容を従プログラムに(OSの機能などを仲介して)メッセージ渡し(message passing)して代わりに処理させることで、検証済みプログラムのソースコードに手を加えることなく、低コストで開発することができる(コルーチンを用いたプログラミング)[12]

オーレ=ヨハン・ダールクリステン・ニガードは、上記のような一連の操作を一つの言語の中で完結させるための機構を提案した[13]。それがクラスの構文である。

高級概念化した型と値の関係としてのクラスとオブジェクト

[編集]

機械語プログラマにとっては、データの各項目は構造を持たない型無しの単なるビットの集まりである。一方で、それよりは高級言語であるALGOL 60のプログラマにとっては、ある一つのデータは整数、実数、ベクトルまたは行列のいずれかの構造を持つデータ型の値である。なお、オーレ=ヨハン・ダールアントニー・ホーアはこのようなものを基本的概念(basic concept)と呼んだ[14]

SIMULAはALGOL 60の拡張言語である。基本概念からなるALGOL 60をより高級にするならば、より高級なデータ型の概念を持つことが求められる。オーレ=ヨハン・ダールは、新たな高級概念(higher level concept)の一つとして、ALGOL 60において制御機構として導入されていたブロック(block)が相当すると提案した。つまり、新たな高級概念としての型と値の関係として、ブロックをデータ型、ブロックが生成する計算するプロセス ―これをインスタンス(instance)と呼ぶ― を値に相当するものとみなせると考えた。ただ、ブロックが生成するインスタンスは、ALGOL 60においては制御が戻ってくると消滅してしまうので、普通は消滅することがないデータ型の値と完全に見なすことができない。そこで、普通のデータ型の値ともみなすことができるように、呼び出して制御が戻ってきても消滅しないインスタンスを生成するブロックとして新たな構文をSIMULAに導入した。

ところで、一般に、基本的概念である構造を持つデータ型は一般にその値の集まりと同一視することができる(整数型=={整数の集まり})。

基本的概念である値と型の関係の一例
(値): (型)
整数  : {整数の集まり}

この関係を新たな高級概念たるブロックに対して適用すると、値に相当するものはインスタンスであり、型に相当するものはインスタンスの集まり(class of instances)である。

ダールの提案した新しい高級概念
インスタンス(ブロックの生成する計算プロセス) : {インスタンスの集まり(class of instances)}

一方で、インスタンスを生成するのはブロックであることから、インスタンスの集まりをブロックと同一視することもできる(ブロック=={インスタンスの集まり})。そこで、この高級概念たる消滅しないインスタンスを生成するブロック概念に相当する構文は、新たにクラス(class)と命名されることになった。さらに、クラスのインスタンスに相当するものをオブジェクト(object)と呼んだ。

抽象データ型としての表現

[編集]

クラスの構文はブロックの概念を構文化したものである。ALGOL 60は変数の宣言や手続き宣言をプログラム中のどこにおいてもよく[15]、ブロック内部においても行うことができた。当然クラスにおいても同様であり、変数宣言と手続き宣言を含むプログラムコードをその内部に完結した形で記述することができる(カプセル化)。このようなクラスの本体に局所的に定義された変数や手続きなどはそのクラスの所属物(attribute)であると呼ばれる。

クラスから生成されるカプセル化条件を満たすオブジェクトは、閉じた状態で疑似並列的に走ることになるが、完全に閉じた状態であるとすると他の計算プロセスと相互作用することがなく、そのままでは走らせる意味がない。したがって、独立して走る計算プロセスに対して、他のプロセスから命令を与える機構が必要となる。同じ計算プロセス上で手続きを呼び出す命令を関数呼び出しと呼ぶ一方、別の独立した計算プロセスに命令を与える操作はメッセージ渡し(message passing)と呼ばれる。

プログラムとして表現することができるものはすべてクラスとして表現することができる。すなわち、クラス概念よりは低級な具体的データ型についてもクラスを用いて表現することができる。

オブジェクト指向プログラミングへ

[編集]

アラン・ケイは、生物の細胞やコンピュータネットワーク上のコンピュータをモデルにしてオブジェクト指向プログラミング(object oriented programming)と呼ばれるものを提唱した[17]。ただし、その内容としては、アイディアが先行したもので具体的な内容に乏しかった[18]

Smalltalkの主要実装者であるダン・インガルスは、Glen Krasner編集の緑本『Smalltalk-80: Bits of History, Words of Advice.』[Krasner, Glenn. 1983]において、オブジェクト指向のプログラミング方法論として以下の3つの特徴

  • データをオブジェクトとして格納し、もし不要になった場合メモリ割り当て回収を自動的に行う。
  • オブジェクトにメッセージを送ることによって処理が進行する。
  • オブジェクトの動作がクラスに記述されている。

を挙げ、「反対意見もあるかもしれないが、我々はこれら3点を『オブジェクト指向』コンピューティングの純正部分と考えている」とオブジェクト指向の整理を行った[19]

この定義は、プログラミング方法論と言語の機能の内容が混在した特徴付けであったが、これを踏まえてルイス・ピンソンとリチャード・ウィナーはその著作の『Smalltalk:オブジェクト指向プログラミング』[20]において、上の3つの特徴付けに「問題に対する段階的な解決をサポートしている」[19]、という条件も追加することを提案した。そして、さらに次のような整理を行った。

まず、ピンソンとウィナーは、課題に対してメッセージを送るというステップの積み重ねで問題の解決を図ることをオブジェクト指向問題解決と定義した[22]

オブジェクト指向プログラミングの四大要素(The Four Pillars of Object-Oriented Programming)

[編集]

上記のオブジェクト指向アプローチにはそこで用いるべきデータ構造や命令セットについては何ら制約はない。だが、実際にプログラミングを行ってオブジェクト指向問題解決を図るにあたっては望ましいオブジェクトの性質というものが存在する。そこで、次にピンソンとウィナーは、オブジェクトが持つべき4つの性質として抽象(abstraction)、カプセル化(encapsulation)、継承(inheritance)、そしてポリモーフィズム(多相性、polymorphism)を挙げ、それをサポートする言語をオブジェクト指向プログラミング言語(Object-Oriented Programming Language:OOPL)と定義した[23]

そして、オブジェクト指向言語を用いてオブジェクト指向問題解決をプログラミングによって図ることを、オブジェクト指向プログラミング(Object-Oriented Programming)というように定義し、その特徴付けを、リバースエンジニアリング的に言語同様に四つの特徴的性質を持つオブジェクトによるプログラミングと定めた[23]

現代においては、ピンソンとウィナーによって定義づけられたこれらオブジェクト指向プログラミングの四つの特徴付けはオブジェクト指向プログラミングの四大要素(The Four Pillars of Object-Oriented Programming)と呼ばれることがある。

抽象(abstraction)

[編集]

最も一般的な意味で、抽象(abstraction)とは複雑な観念や事物の簡潔な表現のことを言う[24]。データ抽象と機能抽象からなる。データ抽象はいくつかの手続型言語でもサポートされており、オブジェクト指向言語特有の特徴ではない。そのため、これを省略してオブジェクト指向の三大要素としてオブジェクト指向を定義されることもある。

データ抽象の例としては、例えば、バスケットに3つのリンゴ、4つのみかんがあるとき、プログラミング言語としては、2つのグローバル変数 numberOfAppleInBasket = 3numberOfOrangeInBasket = 4 で抽象化した表現をとれる。

カプセル化 (encapsulation)

[編集]

カプセル化とは、関連する抽象化した表現をローカルなスコープの領域(特にクラス構文内)にまとめることを言う。オブジェクト指向言語においては、オブジェクトとは抽象のカプセル化である、とも言われる[24]

継承 (inheritance)

[編集]

継承(inheritance)または拡張(extension)の目的は、単純なクラスをそのままにして、それからもっと複雑なクラスを構成することである[25][26]SIMULA 67ではすでに実装されており連接(concatnation)と呼ばれていた[27]

例えば、クラス X を用いて構築したシステム S がすでに稼働しているとき、S に類似したシステムを構築するにあたっては、すでに S の部品として使用されている X のコードに手を入れて崩すことができない(ソースコードが公開されていないこともある)。そのため、すでに稼働実績がある S のコードを効果的に再利用するためには、安全な X の部分を保存したまま拡張部分を付け足すことができればよいが、それを実現する方法が継承である。

ポリモーフィズム (polymorphism)

[編集]

同一のメッセージ・セレクタに対して、異なるいくつかのオブジェクトがそれぞれ適切な反応ができるという能力をポリモーフィズム(polymorphism;多相性、多態性、多様性)という[28]

例えば、オブジェクトごとにその文字列表現を返す ToString がある。概念的には、ToString はある特定の動作の一つを意味し、この概念はどのオブジェクトに対しても同一であるが、その目的から実際の実現の仕方に違いが生じる可能性が残っても良い。

脚注

[編集]
  1. ^ Ole-Johan Dahl, Kristen Nygaard 1966, p. 1.
  2. ^ 山本 喜一 (1981), “プログラミング言語の最新の動向:9. SIMULA”, 情報処理 22 (6), https://ipsj.ixsq.nii.ac.jp/ej/?action=pages_view_main&active_action=repository_view_main_item_detail&item_id=6560&item_no=1&page_id=13&block_id=8 
  3. ^ E.W.ダイクストラ, C.A.R.ホーア & O.-J.ダール 1975, p. 201.
  4. ^ E.W.ダイクストラ, C.A.R.ホーア & O.-J.ダール 1975, p. 202.
  5. ^ 統一モデリング言語 (UML) のクラス図では、データのことを「属性」、振る舞いのことを「操作」と呼ぶ。また具体的なプログラミング言語として、C++などでは、データのことを「メンバー変数」、振る舞いのことを「メンバー関数」と呼ぶ。Javaなどでは、データのことを「フィールド」、振る舞いのことを「メソッド」と呼ぶ。
  6. ^ SIMULA 67では無制限にアクセスできたが、現代的なプログラミング言語では、それぞれにアクセス修飾子を指定できるものもある。
  7. ^ C.A.R.ホーアによる前書きの抜粋
    第3の論文は、前の2つのまとめとして載せているが、ここでは、データの設計とプログラムの設計の間の理論的かつ実際的な深い関連について説明している。また、多くのプログラマにとってなじみがないと思われる、プログラムとデータの構造化の有用な方法を紹介している。ここの例で、構造化プログラミングの減速がプログラムの”下降型”の設計と同様に”上昇型”の設計にも適用できることを示している。この論文の原アイデア、洞察、すべての例は、O.-J.Dahlによっている。私は、それらを編集し、理解しにくいところにいくつか説明を追加しただけである。
  8. ^ Bjarne Stroustrup. “A History of C++: 1979−1991”. 2019年2月2日閲覧。
  9. ^ この時点ではまだオブジェクト指向の概念や用語は確立されていなかったが、のちにSimulaの影響を受けたビャーネ・ストロヴストルップC++[8]と、アラン・ケイSmalltalkによってオブジェクト指向が再定義されることになる。
  10. ^ オブジェクト指向プログラミングにおけるカプセル化継承ポリモーフィズムなどを、クラスベースのオブジェクト指向プログラミングにおいてはクラスを必要に応じて適宜使って実装する。
  11. ^ 一方、カプセル化・継承・ポリモーフィズムなどを、プロトタイプベースのオブジェクト指向プログラミングにおいてはクラスを使わずに実装する。
  12. ^ ただし、随所にOSの機能を利用することになるため異なるOSへの移植性が低い上に、主プログラムと並列呼び出しする従プログラムが異なる言語で記述されている場合、複数の異なるコンパイラが必要となり、場合によっては複数の異なる言語を使用しなければならなくなってしまう。
  13. ^ 言語仕様にクラス構文を導入することで以下のような利益が得られる。
    • 主プログラムと従プログラムに相当するものが異なる言語で記述されることがない。
    • 複数スレッド計算機のOSに依存した以下の一連の操作を言語内部で統一的に処理できるようになる
      • 主プログラムからのメモリ割り当て
      • 並列呼び出し
    • 抽象データ型として表現される場合、OSを仲介したメッセージのやりとりのような形式ではなく、体裁上は具体的データ型のデータに対する処理への引数渡し、処理返しとして取り扱い可能になる
  14. ^ 低級言語たとえば機械語によるプログラミングでは、浮動小数点データに固定小数点演算を施したり、論理変数に算術演算を行ったり、制限範囲外への番地参照を許してしまう種類の非常に単純な誤りが簡単に起きてしまう。このような誤りは高級言語を用いることでコンパイル時のエラー、実行時エラーの形で防ぐことができる。
  15. ^ 山崎 利治『プログラム言語』昭晃堂〈ソフトウェア講座40〉、1989年。  p.25
  16. ^ Dr. Alan Kay on the Meaning of "Object-Oriented Programming"” (2003年). 11 February 2010閲覧。
  17. ^
    私は、オブジェクトとは、生物の細胞やネットワーク上の個々のコンピュータのようもの、そしてそれらのコミュニケーションは専らメッセージによって行なわれるもの、と考えていました (つまり、メッセージングは最初から存在していたのですが、プログラミング言語でメッセージングを実用的かつ効率的に行う方法を見つけるまでには時間がかかりました)。
    アラン・ケイ, Dr. Alan Kay on the Meaning of "Object-Oriented Programming"[16]
  18. ^ 『オブジェクト指向プログラミング』という用語の提唱者はアラン・ケイであるが、オブジェクトという用語を用いた問題解決方法は同時多発的に提唱されたものであり、その定義は明確ではない。
  19. ^ a b L.J.ピンソン & R.S.ウィナー 1990, p. 6.
  20. ^ L.J.ピンソン & R.S.ウィナー 1990.
  21. ^ L.J.ピンソン & R.S.ウィナー 1990, pp. 1–2.
  22. ^ さらに、オブジェクト指向問題解決を図る次の各ステップからなるものをオブジェクト指向アプローチと定義した[21]
    1. 問題について述べる。
    2. 解法において必要なオブジェクトを同定する。
    3. それらのオブジェクトが応答すべきメッセージを同定する。
    4. オブジェクトへ送るメッセージ列をうまく選択して問題を解決する。
  23. ^ a b L.J.ピンソン & R.S.ウィナー 1990, p. 7.
  24. ^ a b L.J.ピンソン & R.S.ウィナー 1990, pp. 7–8.
  25. ^ UMLでは継承のことを汎化 (generalization) と呼んでいる。汎化とはスーパークラスによる抽象化であり、対義語の特化 (specialization) はサブクラスによる具象化を指す。
  26. ^ 継承は、開放/閉鎖原則に基づき、単純な基本クラスからより複雑な派生クラスを構成する機構であり、コードの再利用と拡張を容易にする。逆に複雑なクラスの所属物のいくつかを除いて単純なクラスを構成しようとすると、コードの再利用と拡張を阻害することになる。すなわち、最初から多数の所属物をカプセル化したり、基本クラスから継承するにしても多数の所属物を付け加えて極めて特化されたクラスを最初から作成してしまうと、途中でそれよりやや一般的なクラスが必要になっても代替させることができない。
  27. ^ E.W.ダイクストラ, C.A.R.ホーア & O.-J.ダール 1975, pp. 226–228.
  28. ^ L.J.ピンソン & R.S.ウィナー 1990, p. 64.

関連項目

[編集]

参考文献

[編集]
  • オーレ=ヨハン・ダール, C.A.R. ホーア (1972), 階層的プログラム構造 
    • E.W.ダイクストラ、C.A.R.ホーア、O.-J.ダール 著、野下浩平,川合慧,武市正人 訳『構造化プログラミング』サイエンス社、1975年。  (収録)
  • Ole-Johan Dahl (2001), The Birth of Object Orientation: the Simula Languages, https://www.mn.uio.no/ifi/english/about/ole-johan-dahl/bibliography/the-birth-of-object-orientation-the-simula-languages.pdf 
  • Ole-Johan Dahl, Kristen Nygaard (1966), SIMULA : an ALGOL Based Simulation Language, https://dl.acm.org/doi/pdf/10.1145/365813.365819 
  • Ole-Johan Dahl, Bjørn Myhrhaug, Kristen Nygaard (1970). SIMULA 67 Common Base Language. https://www.ics.uci.edu/~jajones/INF102-S18/readings/10_Simula.pdf 
  • L.J.ピンソン、R.S.ウィナー『Smalltalk:オブジェクト指向プログラミング』富士ゼロックス情報システム(現:富士フイルムシステムズ)(訳)、トッパン〈アジソンウェスレイ・トッパン 情報科学シリーズ〉、1990年。ISBN 4-8101-8011-5 
  • R.S.ウィナー、L.J.ピンソン『C++:オブジェクト指向プログラミング』前川守(訳)、トッパン〈アジソンウェスレイ・トッパン 情報科学シリーズ〉、1989年9月。ISBN 4-8101-8009-3 (上記の姉妹本)