第3章では「制御フローをどう構造化するか」という問いを見ました。しかしソフトウェアが巨大化するにつれ、 もう一つの問いが切実になります——「データとそれを操作するコードを、どう整理するか」。 この問いへの強力な答えがオブジェクト指向プログラミング(OOP)でした。 本章では、北欧の小さなシミュレーション言語から始まり、やがて世界の主流となるOOPの興隆を辿ります。
起源 — Simula 67、現実を「もの」として捉える
OOPの起源は、意外にもシミュレーションにありました。ノルウェー計算センターのオーレ=ヨハン・ダールと クリステン・ニガードは、船舶の交通や工場の動きといった現実世界をコンピュータで模擬しようとしていました。 そこで彼らが直面したのが「現実の『もの』(船、客、窓口)を、プログラム内でどう自然に表現するか」という課題です。
その答えとして1967年に発表されたのが Simula 67 です。彼らは「もの」を表す設計図=クラス(class)と、 その実体=オブジェクト(object)という概念を導入しました。さらに、似たクラスの共通部分を引き継ぐ 継承(inheritance)、実行時に適切な振る舞いを選ぶ動的束縛(dynamic binding)—— 今日のOOPの基本概念が、ここでほぼ出揃ったのです。Simula 67は「最初のオブジェクト指向言語」とされ、 ダールとニガードは2001年のチューリング賞に輝きました。
純粋への追求 — Smalltalk と Alan Kay
Simulaの種は、1970年代にゼロックスのパロアルト研究所(Xerox PARC)で花開きます。 アラン・ケイ、ダン・インガルス、アデル・ゴールドバーグらが開発した Smalltalk です。 ケイはOOPの概念を極限まで純化しました——「すべてがオブジェクトであり、計算とはオブジェクト間のメッセージ送信である」。
数値も、文字も、クラスそのものさえもオブジェクト。3 + 4 ですら「オブジェクト3に、引数4とともに + という
メッセージを送る」と解釈されます。この徹底ぶりが「純粋オブジェクト指向」と呼ばれる所以です。
Smalltalkはまた、重なり合うウィンドウやマウス操作といった現代的なGUIの発祥地でもあり、
「オブジェクト指向」と「直感的なユーザー体験」が同じ研究室で生まれたのは偶然ではありませんでした。
"Smalltalk: すべてはメッセージ送信"
| account |
account := BankAccount new. "オブジェクトを生成"
account deposit: 100. "depositメッセージを送る"
account withdraw: 30.
Transcript show: account balance printString. "=> 70" OOPの3本柱
Simula と Smalltalk が確立したOOPの中核概念は、しばしば3本柱として整理されます。 これは大規模ソフトウェアの「理解と保守の困難」という問題への、具体的な処方箋でした。
| 柱 | 意味 | 何を解決するか |
|---|---|---|
| カプセル化 (encapsulation) | データと操作を1つにまとめ、内部を隠す | 内部実装を変えても外部に影響しない。情報隠蔽 |
| 継承 (inheritance) | 既存クラスの性質を引き継いで拡張する | コードの再利用、共通部分の一元管理 |
| 多態性 (polymorphism) | 同じ呼び出しが対象に応じて異なる振る舞いをする | 具象に依存しない柔軟な設計。拡張に開く |
実用への接ぎ木 — C++(1979→1985)
OOPが研究室から実務の世界へ躍り出る決定打が C++ でした。 ベル研究所のビャーネ・ストロヴストルップは、Simulaのオブジェクト指向の表現力と、Cの実行効率を両立させたいと考えました。
彼は1979年に「C with Classes」として開発を開始。Cにクラスを接ぎ木したこの言語は、
1983年に「C++」と改名されます(++ はCのインクリメント演算子、「強化されたC」の意)。
最初の商用版は1985年にリリースされ、同年ストロヴストルップの著書『The C++ Programming Language』が世に出ました。
#include <iostream>
#include <string>
class Animal { // クラス: 設計図
public:
virtual std::string sound() const { return "..."; } // 多態の準備
};
class Dog : public Animal { // 継承
public:
std::string sound() const override { return "ワン"; }
};
int main() {
Dog d;
std::cout << d.sound() << std::endl; // => ワン
} C++の戦略は「既存のCプログラマをそのまま取り込む」ことでした。Cのコードはほぼそのままコンパイルでき、 必要に応じてOOPを段階的に導入できる。この実用主義と後方互換性が、C++を爆発的に普及させました。 半面、CとOOPの両方を抱え込んだことで言語は巨大で複雑になり、「機能の多さ」は後年まで賛否を呼ぶことになります。
大衆化 — Java と「Write Once, Run Anywhere」
OOPを真に「業界標準」へ押し上げたのは Java です。サン・マイクロシステムズのジェームズ・ゴスリンらが開発し、 1995年に公開されました。当初の名は Oak(オフィス外の樫の木に由来)でしたが、 商標の都合で「Java」(コーヒー)に改名されたエピソードは有名です。
Javaの革命は2つありました。第一に、仮想マシン(JVM)とバイトコードによる 「Write Once, Run Anywhere(一度書けばどこでも動く)」。ソースをJVM向けの中間コードにコンパイルし、 各OSのJVMが実行するため、プラットフォームの違いを吸収できます。第二に、LISP由来のガベージコレクションを 主流言語として標準装備し、C/C++で悩みの種だった手動メモリ管理から開発者を解放しました。
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
} Javaの「クラスが必須で、すべてをクラスの中に書く」スタイルは、上の単純なHello Worldの冗長さにも表れています。 これはSmalltalkの純粋さとも、C++の自由さとも違う、「規律ある大規模開発」を志向した設計でした。 企業システム、そしてのちにAndroidを支え、Javaは2000年代を通じて世界でもっとも使われる言語の座を占めます(第8章)。
graph TD SIM[Simula 67\n1967 クラス・継承] ST[Smalltalk\n1970s 純粋OOP・メッセージ] CPP[C++\n1979-85 CにOOP接ぎ木] OC[Objective-C\n1984 C+Smalltalk] JV[Java\n1995 JVM・GC・WORA] CS[C#\n2000 Microsoft] SIM --> ST SIM --> CPP ST --> OC CPP --> JV CPP --> CS JV --> CS style SIM fill:#3b82f6,stroke:#1d4ed8,color:#fff style ST fill:#8b5cf6,stroke:#6d28d9,color:#fff style CPP fill:#f97316,stroke:#ea580c,color:#fff style JV fill:#22c55e,stroke:#15803d,color:#fff
Simula 67
ダール & ニガード。クラス・オブジェクト・継承・動的束縛。最初のOO言語(2001年チューリング賞)
Smalltalk
Xerox PARC、アラン・ケイら。「すべてがオブジェクト、すべてがメッセージ」。GUIの発祥地
C with Classes
ストロヴストルップがCにクラスを追加。1983年に「C++」と改名
Objective-C
CにSmalltalk流メッセージングを融合。後にApple/NeXTで採用
C++ 商用版リリース
同年『The C++ Programming Language』初版。実用OOPの本格普及
Java 公開
JVM・GC・WORA。元名Oak。企業開発とAndroidを席巻していく
C#
Microsoft、アンダース・ヘルスバーグ。.NETとともにJava的OOPを継承
理解度チェック
最初のオブジェクト指向言語とされ、クラス・オブジェクト・継承の概念を導入した言語はどれですか?
キーボード: 1〜4 で選択、Enter で回答