4-2. オブジェクト指向の原則
このセクションで学ぶこと
Section titled “このセクションで学ぶこと”- クラスとインスタンスの基本
- カプセル化・継承・ポリモーフィズムの意味
- オブジェクト指向が、プログラムを整理するのにどう役立つか
- JavaScript のクラス例を通して、概念を具体的に見る方法
1. なぜオブジェクト指向が必要なのか
Section titled “1. なぜオブジェクト指向が必要なのか”プログラムが小さいうちは、変数と関数だけでもある程度は書ける。
しかし機能が増えてくると、次のような問題が起きやすくなる。
- どのデータに、どの処理が対応するのか分かりにくい
- 同じような処理があちこちに散らばる
- 一部の変更が、別の場所へ予想外の影響を与える
そこで登場する考え方の 1 つがオブジェクト指向である。
オブジェクト指向では、データと、そのデータに対する操作を近くにまとめて考える。
データだけが散らばる状態- name- price- updatePrice()- validatePrice()
↓
1つの対象としてまとめるBook- title- price- updatePrice()- validatePrice()これにより、「この処理は何に対する処理か」が見えやすくなる。
2. クラスとインスタンス
Section titled “2. クラスとインスタンス”オブジェクト指向を理解する最初の入口が、クラスとインスタンスである。
| 用語 | 意味 |
|---|---|
| クラス | オブジェクトの設計図 |
| インスタンス | 設計図から作られた実物 |
class Book ↓┌─────────────┬─────────────┐│ Book("Git") │ Book("DB") │└─────────────┴─────────────┘JavaScript の例で見ると、次のようになる。
class Book { constructor(title) { this.title = title; }}
const book1 = new Book("Git Basics");const book2 = new Book("DB Basics");Bookがクラスbook1とbook2がインスタンス
this とは何か
Section titled “this とは何か”this は、いま操作しているそのインスタンス自身を表す。
book1.title は book1 のタイトル、book2.title は book2 のタイトルになる。
つまり同じクラスから作られていても、インスタンスごとに持つ値は異なる。
3. カプセル化とは何か
Section titled “3. カプセル化とは何か”カプセル化とは、内部データと操作をまとめ、外から勝手に壊されにくくする考え方である。
たとえば口座残高を管理するとき、外部コードが好き勝手に値を書き換えられると危険である。
そこで「残高はメソッド経由でしか変えない」という形にすると、安全性が上がる。
class BankAccount { #balance = 0;
deposit(amount) { if (amount <= 0) { throw new Error("amount must be positive"); } this.#balance += amount; }
getBalance() { return this.#balance; }}ここで何が守られているのか
Section titled “ここで何が守られているのか”- 残高そのものは
#balanceに閉じ込められている - 入金は
deposit()というルール経由でしか行えない - 不正な値はメソッド内で検査できる
つまりカプセル化は、「外から見えなくすること」だけでなく、状態を壊れにくくすることが目的である。
4. 継承とは何か
Section titled “4. 継承とは何か”継承とは、共通する性質を親クラスにまとめ、子クラスがそれを引き継ぐ仕組みである。
class Animal { constructor(name) { this.name = name; }
speak() { console.log(`${this.name} makes a sound`); }}
class Dog extends Animal { speak() { console.log(`${this.name} barks`); }}この例では、Dog は Animal を継承している。
nameという共通データは親から受け継ぐspeak()は子クラス側でより具体的に書き換えられる
- 共通部分をまとめやすい
- 似た対象をグループとして扱いやすい
- 変更箇所を集約しやすい
ただし継承は「何でも使えばよい便利機能」ではない。
まずは共通部分を親へまとめる考え方を理解することが大切である。
5. ポリモーフィズムとは何か
Section titled “5. ポリモーフィズムとは何か”ポリモーフィズムとは、同じ操作名で呼び出しても、実体によって振る舞いが変わるという考え方である。
class Cat extends Animal { speak() { console.log(`${this.name} meows`); }}
const animals = [new Dog("Pochi"), new Cat("Tama")];
for (const animal of animals) { animal.speak();}このコードでは、animal.speak() という同じ呼び出しをしているのに、実際の出力は次のように変わる。
Pochi barksTama meowsこれがポリモーフィズムの基本である。
なぜ便利なのか
Section titled “なぜ便利なのか”ポリモーフィズムがないと、呼び出し側で大量の if や switch を書いて「犬ならこれ、猫ならこれ」と分けたくなりやすい。
しかしオブジェクト側へ振る舞いを持たせると、呼び出し側は共通の操作だけを知っていればよい。
6. 3 つの原則をまとめて見る
Section titled “6. 3 つの原則をまとめて見る”カプセル化 : データと操作をまとめ、壊れにくくする継承 : 共通部分をまとめて引き継ぐポリモーフィズム : 同じ操作名で対象ごとに振る舞いを変えるこれら 3 つは別々の知識ではなく、次のように組み合わさる。
- クラスで対象の構造を定義する
- カプセル化で状態を守る
- 継承で共通部分をまとめる
- ポリモーフィズムで呼び出し側を単純にする
実務では、オブジェクト指向を使う目的は「難しい設計用語を覚えること」ではなく、変更に強く、読みやすいコードにすることである。
7. 初学者が混同しやすい点
Section titled “7. 初学者が混同しやすい点”クラスとインスタンスは違う
Section titled “クラスとインスタンスは違う”クラスは設計図、インスタンスは実物である。
Book と book1 は同じものではない。
継承は単なるコピペではない
Section titled “継承は単なるコピペではない”親クラスの共通ルールを活用しつつ、子クラスで必要な差分を持たせる考え方である。
ポリモーフィズムは「同じ結果」ではない
Section titled “ポリモーフィズムは「同じ結果」ではない”同じ操作名で呼べることが重要であり、結果は対象ごとに違ってよい。
カプセル化は隠すことそのものが目的ではない
Section titled “カプセル化は隠すことそのものが目的ではない”目的は、内部状態を壊れにくくし、ルールを守りやすくすることである。
| キーワード | 説明 |
|---|---|
| クラス | オブジェクトの設計図 |
| インスタンス | クラスから作られた実物 |
this | いま操作しているインスタンス自身 |
| カプセル化 | データと操作をまとめ、状態を守る考え方 |
| 継承 | 共通部分を親クラスへまとめて引き継ぐ仕組み |
| ポリモーフィズム | 同じ操作名で対象ごとに振る舞いを変える考え方 |
| メソッド | クラスの中に定義された関数 |
次のステップ
Section titled “次のステップ”演習問題 に取り組んで理解を確認しよう。
理解できたら 4-3. 例外処理・ログの考え方 へ進もう。