- 1967年Simulaを皮切りに多くのオブジェクト指向言語が生まれた
- Simula、Smalltalk、C++と他のC拡張、Javaを調査する
- この章では、言語に関する詳細な比較評価はせず、問題 と 概念 について学ぶことである
- クラス家の創立者
- 1967年に完成
- 構造化プログラミングや、情報隠蔽、抽象データ型といった技術が話題になる前に誕生した
- Simulaは二度の設計を経ている
- 60年代の初期に「Simula1」が離散的イベントシミュレーションプログラミングを支援するために開発された
- 本来のSimulaは1967年に設計された「Simula67」である
- Simulaという名前は多くの人に離散的イベントシミュレーションのためだけの言語であるというイメージを喚起させてしまった
- シミュレーションを担うのは一握りの命令とSIMULATIONライブラリクラスだけであった
- 1986年に単なるSimulaに短縮され、1987年に標準化された
- Simulaは尊敬すべきではあるが廃れた先祖として扱われるが、まだ、小さいが熱心なコミュニティの支援を受けている(この本の執筆時なので現在はさらにそれより小さそう)
- SimulaはAlgol60のオブジェクト指向拡張である
- 基本的な制御構造はAlgolのそのままである
- メインプログラムの概念
- クラス単位でコンパイル可能
- 自動ガーベジコレクションのサポート
- Simulaは単一継承をサポートする
A class B;
begin ... end
- 子クラスにおけるクラスの再定義は、新しい宣言を子クラスでするだけで良い
redefine
句に対応するものはない
- Simura67のオリジナルでは、情報隠蔽機構はなかったが、最近の版では
protected
: 顧客に利用させたくない場合に宣言するhidden
: ある子孫に対してその機能を利用不可能にできる
virtual
で仮想ルーチンを提供する
class POLYGON;
virtual: procedure set_vertices
- POLYGONを継承するTRIANGLEやQUADRANGLEで、
set_vertices
の引数を変更可能にする- 型チェックが実行時に行われる
- 多相性を提供する
qua
を使うことで、動的束縛を可能にする
ref(A) a1;
ref(B) b1;
...
a1 :- b1;
a1.f //=> Aのf
(a1 qua B).f //=> Bのf
inspect
命令でインスタンスa1
のクラスに応じて処理を分けることが可能
inspect a1
when A do ...;
when B do ...;
XXX: 本文参照
- Simulaはコルーチンを提供する
- 単一のスレッドで動作する擬似的な並列処理
resume
とdetach
命令でコルーチンを操作する- 各機能がシーケンシャルなプロセスで記述され、主従関係が適切でないときに有用
- 入力と出力のファイルの構造に異なる制約が置かれる場合の、入力から出力への変形
- Simulaのクラスは本体(body)を持っており、通常インスタンスの初期化に使われるが、コルーチンではそれがプロセスに当たる。
while continuation_condition do begin
...Actions...
resume other_coroutine;
...Actions...
end
- コルーチンオブジェクトを作成するメインプログラムを生成し、それらのうちの一つを再開する
corout1 :- new C1; corout2 :- new C2,...
resume corout1
C1
を生成したあとにC1のプロセスが開始されるとメインスレッドが制御を取り戻せずC2
を生成できなくなるdetach
命令を通して制御を取り戻す- コルーチン本体はたいていdetachから始まり、その後にループが続き、メインプログラムまたは他のコルーチンが
resume
するまで保留される
- コルーチン本体はたいていdetachから始まり、その後にループが続き、メインプログラムまたは他のコルーチンが
- 与えられた実数のシーケンスを印刷する。ただし、
- 8の倍数の番の数値はスキップすること
- 6個出力したら改行すること
- 与えられた数のうち最初の1000個のみ含めること
- この問題は、限定されたロジックを持つ3つのプロセスを含んでいるのでコルーチンを使用する代表的な例
- 3つのコルーチン
- プロデューサー(入力)
- プリンタ(出力)
- コントローラ
- クラスCが親Aを持っている場合、本体の実行順序は、
actual_bodyA; bodyC
になる
- この実行順序が望むものでないとき、
inner
命令を使って変更可能 - Aの本体を次のように書けば、
instructions1; inner; instructions2
Cのbodyの実行順序は、
installation1; bodyC; installation2
になる。 が、不便である
- 基本的にインスタンスを作る必要あることが多い
- Cのような子孫の本体は複雑になっていく
- Simulaは離散的イベントシミュレーション用として1セットのプリミティブを持っている
- シミュレーションのソフトウェアシステムは、外部システムの振る舞いを分析し、予測する
- 離散的イベントシミュレーションのソフトウェアシステムは、任意の時点で、不連続の瞬間で生じるイベントに応じて変わる状態を持つ外部システムをシミュレートする
- 分析的なモデリングは、外部システムを数学的なモデルを構築し、その方程式を解決するアプローチ
- 離散的イベントシミュレーションは長時間にわたって外部システムをシミュレートしなければならないので、分析的なモデルは効率的である
- しかし、多くの物理的なシステムは複雑すぎるので現実的で制御しやすい数学的なモデルを導くことができない
- 多くの外部システムは、離散的イベントがシミュレーションに本質的に向いている
- 離散的イベントモデルは、外部システム時間、またはシミュレート時間と呼ばれる時間をトラッキングしなければならない
- こういったシミュレーション独特の機能は、ライブラリクラス
SIMULATION
で提供される - SIMULATIONはクラスPROCESSの宣言を含んでいる
- プロセスは次の4状態のうち一つになる
- 活動中(active)
- 保留された(suspended)
- アイドル中(idle)
- 修了した(terminated)
XXX: 本文参照
- Algol60同様商用的成功には恵まれなかったが、多くの知的影響を後続の言語に与えた。
- 商用的失敗の重要な原因は、「早く来すぎた」こと
- Smalltalkに対するアイデアはAlan Kayとグラフィックスの分野において活動中だったグループにおいてユタ大学で1970年頃に固められた
-
Smalltalkは型がないスタイルのLispとSimulaの影響を組み合わせている
-
動的束縛を採用し型チェックは実行しない
-
オブジェクトに対して「メソッドを送る」
-
特徴として、クラスとオブジェクトの明確な区別が欠如している
- Smalltalkシステムの中のすべては、クラス自身を含めてオブジェクト
- クラスは、メタクラスと呼ばれるより高いレベルのクラスのインスタンスとして見られる
- クラス階層がシステムの中の要素すべて包含することを可能にする
- 階層のルートにはobjectと呼ばれるもっとも高いレベルのクラスがある
-
このアプローチは
- 一貫性: すべてオブジェクトに従う
- 環境有効性: シンボリックデバッガが作りやすくなる
- クラスメソッド: インスタンスに対するだけでなく、クラスに対してもメソッドを定義できる
- Smalltalkは、単項演算子、キーワード、二項演算子の3つの形式のメッセージを定義する
- 単項メッセージ: パラメータのないメソッド呼び出し
acc1 balance
- キーワードメッセージ: 引数をもったメソッド呼び出し
point1 translateBy: vector1
window1 moveHor:5 Vert:3
- 二項演算子: 算術演算する。が、優先順位はないため括弧を用いて演算順位をプログラマが細かく制御する必要がある
- Smalltalkのクラスはメソッドだけを公開する。属性を公開するためには、その値に対して、アクセスするメソッドを定義する必要がある
- 継承は、単一継承に制限されている
- 再定義されたメソッドからオリジナルの呼べるように、
super
が提供されている
- 再定義されたメソッドからオリジナルの呼べるように、
- 束縛はすべて動的である
- 暫定ルーチンはないが、有効な定義がCの適切な子孫にだけ現れるメソッドに対応するメッセージをクラスCが受け取った時にエラーを起こすための実行時メカニズルムを提供している(Rubyでもよく書く)
rotate: anAngle around:a Point ||
self shouldNotImplement
- Smalltalkの魅力は、プログラミングを支援する環境にある
- ガーベジコレクションのサポート
- コレクション、辞書といったライブラリの提供
- 静的片付けの欠如は、Smalltalkで開発されたソフトウェアシステムの効率に恐ろしい障害を証明した
- Smalltalkはオブジェクト技術の概念に対話型の技術を関連させることにより、Simulaの抽象オブジェクトを理解可能な視覚的なオブジェクトに変え、大観衆に訴えるのに役にたった
- CあるいはC的な開発にノーという人が惹きつけられた
- Lispの衰退によってSmalltalkに流れた
- Smalltalkはプロトタイプを作り実験するために優れたツールである
- 企業がSmalltalkに重要な生産開発を任せることは合理的ではない
- Lispは、備えている言語機能の特性からいくつかのオブジェクト指向の拡張の基礎として役立った
- オブジェクト生成への高度に動的なアプローチ
- ガーベジコレクションをもった自動的なメモリ管理
- 木のようなデータ構造の簡単な表現
- 豊富な開発環境
- 動的束縛の実装を促進する操作の実行時選択
- 1980年代終わりの近く、非オブジェクト指向であるCに対してオブジェクト指向拡張を追加した言語、Objective-cやC++が商業的成功に起因した
- Objective-cは 直交 のアプローチ
- 予期しない衝突を回避して移行をより容易にするもの
- C++は 合併 のアプローチ
- より一貫して言語に結びつくもの
- Brad CoxによってStepstone Corporationで設計された
- CにSmalltalkの概念を直交させたもの
- NEXTSTEPワークステーションとOS用の基本言語
- 重点は多相性と動的束縛にあるが、静的な型付けを提供することによりSmalltalkモデルから離れた
Proceedings: Publication {id date, place; id articles;}
+ new { return [[super new] initialize]}
- initialize { articles = [OrderedCollection new]; return self;}
- add: anArticle { return [contents add: anArticle]; }
- remove: anArticle { return [contents remove: anArticle]; }
- (int) size { return [contents size]; }
- 1986年頃AT&Tベル研究所において、Bjarne Stroustrupによって設計された
- 産業的開発の首位を素早く獲得
- Cとほとんど完全に上位互換性を保つ
- 情報隠蔽
- 継承の支援。オリジナルのバージョンは単一継承のみだったが、現在は多重継承を提供している
- 静的束縛。仮想関数による動的束縛もサポート
- 純粋仮想関数は暫定の機能に似ている
- Cよりも厳密な型付け
- GCはない
- デストラクタの概念
- 例外処理
- 試行代入の形式。ダウンキャスト
- 総称性の形式。テンプレート
- 演算子オーバーロード
- assert命令(前提条件、終了条件、クラス不変式といった契約の支援ではない)。
- さまざまな供給者から入手可能なライブラリ
- C++のサイズは初期の版から相当に増大した
- C++の提案者自身がその機能について必要性があるのかどうか疑問視しているものもある
- プログラミング言語は、堅固で、強力で完全に理解される合理的な個数の概念に基づくべきである
- それほど習慣的でなかったオブジェクト技術の開発を後押ししたことが、C++の最大の長所である
- バイトコードとバイトコードプログラムを解釈実行するバーチャルマシンという実装技術が言語としての成果
- 再コンパイルが不要というアドバンテージ
- (総称性がないという話だがJava 5で導入された)
- 問題:
- 表明支援がない
- 実行時型チェックに対する部分的な信頼
- 複雑なモジュールの構造(クラス、パッケージ、ソースファイル)
- Cから残された不可解な構文
- 問題はあるが、ポータブルソフトウェアの開発に対して作った貢献を減じるものではない
- Oberon
- Modula-2の後継者でプログラミング、ハードウェア支援も含んでいるより一般的なプロジェクトの一部
- Modula-3
- Modula-2を基とするクラス状のレコード型をもったモジュール言語
- Trellis
- Sather
- Beta
- Self
- クラスはなく、型の間ではなくオブジェクト間の関係として継承を支援する「プロトタイプ」に基づく
- Ada 95
- Borland Pascal