オブジェクト指向プログラミング(OOP)とは? 手続き型とは何が違うのか
プログラミングを勉強していると、必ず出会う言葉があります。
「これはオブジェクト指向で書くべきです。」
初めて聞くと、少し途方に暮れる言葉ですよね。手続き型とは何で、オブジェクト指向とはどれほど違うのか、なかなかイメージしにくいものです。
結論から言うと、手続き型は「何をどの順番で行うか」に集中し、オブジェクト指向は「誰がその仕事を担うか」に重きを置きます。データと、それを扱う機能を一つにまとめるか、分けて置くかの違いです。
この記事では、コーヒーの注文にたとえて両者の違いをわかりやすく説明し、実際のコードでどう変わるのかまで紹介します。
手続き型プログラミングは料理のレシピ
手続き型は名前のとおり、「手続き」、つまり順序に重点を置く方法です。
データがあり、それを処理する関数は別々に存在します。上から下へ、順番どおりに処理が進みます。
料理のレシピを思い浮かべるとぴったりです。材料を洗い、切り、炒め、盛り付ける。この順序をそのままコードにしたものが手続き型です。
簡単な口座の例を見てみましょう。
var balance = 10000 // データ
func deposit(amount: Int) { // 機能は別々
balance += amount
}
deposit(amount: 5000)
print(balance)
// 出力: 15000
balanceというデータが外部に公開されていて、deposit関数がそれを直接変更します。
小さなプログラムなら、むしろ簡単で高速です。問題はプログラムが大きくなったときに起こります。
口座が100個に増え、残高を変更する関数があちこちに散らばると、どこで値が変わったのか追跡するのが本当に難しくなります。
オブジェクト指向プログラミング(OOP)とは?
オブジェクト指向では、データと機能を一つにまとめます。このまとまりを「オブジェクト」と呼びます。
口座なら、「残高」というデータと「入金する」という機能を一つのまとまりにするわけです。
先ほどの口座をオブジェクトに変えてみましょう。
class Account {
private var balance = 10000 // データを内部に隠す
func deposit(_ amount: Int) { // 機能も一緒にする
balance += amount
}
func show() { print(balance) }
}
let myAccount = Account()
myAccount.deposit(5000)
myAccount.show()
// 出力: 15000
balanceはprivateとして隠されました。これで外部から残高を自由に変更できません。必ずdepositのような決められた経路だけからアクセスします。
これがオブジェクト指向の核心です。データを保護し、「誰がこの仕事を担うのか」を明確にします。
コーヒーの注文にたとえると、こうです。手続き型は自分で豆を挽き、お湯を沸かし、すべてを行う方法。オブジェクト指向は「バリスタさん、アメリカーノをお願いします」と任せる方法です。作り方はバリスタオブジェクトが自分で責任を持ちます。
OOPの4つの基本的な特徴
オブジェクト指向には4つの柱があります。用語は難しそうですが、概念はシンプルです。
- カプセル化:データを隠し、決められた経路からだけアクセスさせる(先ほどのprivateのようなもの)
- 継承:既存クラスの機能を受け継いで再利用する
- ポリモーフィズム:同じ命令でも、オブジェクトごとに異なる動作をする
- 抽象化:複雑な内部を隠し、必要なものだけを公開する
特にポリモーフィズムは強力です。「鳴いて」と命令すると、犬はワンワン、猫はニャーと鳴くようなものです。命令は一つでも、オブジェクトごとに自動で異なる反応をします。
いつオブジェクト指向を使い、いつ手続き型を選ぶべきか
常にオブジェクト指向が正解とは限りません。状況に応じて選びましょう。
| 状況 | 適した方法 |
|---|---|
| 短いスクリプト、一度きりの計算 | 手続き型 |
| データの流れが単純で順番どおり | 手続き型 |
| 規模が大きく、成長し続けるプロジェクト | オブジェクト指向 |
| 複数人で協業するコード | オブジェクト指向 |
| 似た概念が繰り返し登場する | オブジェクト指向 |
小さく単純なら手続き型のほうがすっきりし、大きく複雑で長く保守するコードならオブジェクト指向が力を発揮します。
手続き型は順序を設計し、オブジェクト指向は責任を設計します。
面接ではこう聞かれます
Q. 手続き型とオブジェクト指向の最大の違いは何ですか? A. データと機能の関係です。手続き型ではデータと関数が分離され、順序を中心に処理が進みます。オブジェクト指向では両者をオブジェクトにまとめ、責任単位で管理します。そのため、規模が大きくなるほど保守や協業に有利です。
Q. カプセル化はなぜ重要ですか? A. 外部からデータを直接変更できないようにして、予期しない変更を減らせるからです。決められたメソッドだけでアクセスするためバグを追跡しやすく、内部実装を変えても外部コードへの影響を抑えられます。
用語は大げさに見えても、結局の核心は「データをどう扱うか」という一点です。
小さなコードからオブジェクトにまとめる練習をすれば、すぐに感覚がつかめるはずです。今日学んだことを生かして、自分のコードを一か所だけでもリファクタリングしてみてください。

