はじめに
オブジェクト指向プログラミング(OOP)は、単にクラスを使ってデータと操作をまとめるだけではありません。その真価は、「オブジェクト指向の三本柱」とも呼ばれる、以下の3つの強力な概念を理解し、活用することで発揮されます。
- カプセル化 (Encapsulation)
- 継承 (Inheritance)
- 多態性 (Polymorphism / ポリモーフィズム)
これらの概念は、プログラムの再利用性、保守性、拡張性を劇的に向上させるために設計されています。この記事では、オブジェクト指向を支えるこの三本柱について、それぞれの役割と目的を初心者向けに分かりやすく解説します。
1. カプセル化 (Encapsulation)
カプセル化とは、①データ(メンバ変数)と、それを操作する手続き(メンバ関数)を、クラスという一つのカプセルにまとめること、そして②外部から直接アクセスされたくない重要なデータを隠蔽(いんぺい)すること、という2つの側面を持つ概念です。
薬のカプセルをイメージすると分かりやすいでしょう。カプセルは、中の薬(データ)を守り、利用者はカプセルの外側から決められた方法(飲む)でしか、その効果(操作)を得られません。
目的とメリット
C++では、メンバを private
にすることで、外部からの直接アクセスを禁止できます。これにより、オブジェクトの内部データが意図せず書き換えられるのを防ぎ、**安全で信頼性の高い部品(オブジェクト)**を作ることができます。
class BankAccount {
private:
long balance; // 残高(外部から直接変更させない)
public:
void deposit(long amount) { // 入金という公開された操作
if (amount > 0) {
balance += amount;
}
}
};
2. 継承 (Inheritance)
継承とは、既存のクラス(親クラス)の性質(メンバ変数やメンバ関数)を引き継いで、新しいクラス(子クラス)を定義する仕組みです。子クラスでは、親クラスの機能に加えて、独自の機能を追加したり、一部の機能を変更(オーバーライド)したりできます。
例えば、「動物」クラスを親として、「犬」クラスや「猫」クラスを作成するようなイメージです。「犬」も「猫」も、共通して「食べる」「寝る」といった「動物」の性質を持っていますが、「犬」は「吠える」、「猫」は「ニャーと鳴く」という独自の機能を持っています。
目的とメリット
既に存在するクラスを再利用できるため、コードの重複を減らし、開発効率を向上させます。また、共通の基盤(親クラス)を持つことで、プログラム全体の構造が整理され、拡張性も高まります。
// 親クラス
class Vehicle {
public:
void moveForward() { /* 前進する処理 */ }
};
// Vehicleクラスを継承した子クラス
class Car : public Vehicle {
public:
void turnOnWipers() { /* ワイパーを動かす独自機能 */ }
};
3. 多態性 (Polymorphism / ポリモーフィズム)
多態性(ポリモーフィズム)とは、ギリシャ語で「多くの形を持つ」という意味で、プログラミングにおいては「同じメッセージ(命令)を送っても、オブジェクトの種類によって異なる応答(動作)をする」性質を指します。
例えば、「描画する (draw
)」という同じ命令を送ったときに、「円」オブジェクトは円を、「四角形」オブジェクトは四角形を描く、といった具合です。
目的とメリット
多態性を利用すると、オブジェクトの種類をいちいち if
文で細かく場合分けする必要がなくなり、処理を共通化できます。これにより、新しい種類のオブジェクト(例: 「三角形」オブジェクト)が追加されても、呼び出し側のコードを修正する必要がなくなり、柔軟で拡張性の高いプログラムを作成できます。
// 異なるオブジェクトに同じメッセージを送る
shape1->draw(); // shape1が「円」なら円を描画
shape2->draw(); // shape2が「四角形」なら四角形を描画
まとめ
今回は、オブジェクト指向プログラミングを支える三つの重要な柱、「カプセル化」「継承」「多態性」について解説しました。
- カプセル化: データを保護し、安全な部品を作る。
- 継承: 既存のコードを再利用し、効率的に拡張する。
- 多態性: 処理を共通化し、柔軟なプログラムを作る。
クラスを定義してオブジェクトを使うだけでも、コードを整理する上で十分に役立ちます。しかし、これら三本柱の概念を理解し、適切に活用することで、オブジェクト指向の真の力を引き出し、大規模で複雑なソフトウェアにも対応できる、高品質なプログラムを設計できるようになります。