「部品」としてプログラムをとらえる¶
〜オブジェクト指向の考え方〜
🔹章のねらい
- メソッドを「部品」として使う発想から、さらに「データと処理をまとめた部品=オブジェクト」への意識を育てる。 -「設計する」という視点に触れさせ、オブジェクト指向の世界への足がかりとする。
- 現実世界のメタファーや図を使い、概念のイメージを明確に持てるようにする。
1. プログラムは「部品の組み合わせ」でできている¶
プログラムを書くとき、私たちは一つの大きな命令のかたまりを書くのではなく、小さな処理の「部品」を組み合わせて全体を作っていきます。
● メソッド=処理の部品
前の章では、メソッドを使って処理を小さく分けましたね。
public static int add(int a, int b) {
return a + b;
}
このように、加算処理を add という名前の部品にしておけば、他の場所から簡単に呼び出せて、再利用もしやすくなります。 これは「処理を部品としてまとめる」という発想でした。
たとえば、こんなプログラムを考えてみましょう。
- ゲームのキャラクターを操作する
- 買い物アプリで商品をカートに入れる
- 銀行口座でお金を預けたり引き出したりする
こうした例では、単なる「処理」だけでなく、
- キャラクターの名前やHP
- 商品の名前や値段
- 口座番号や残高
など、「状態(データ)」と「処理(動作)」の両方を1つにまとめたいというニーズが出てきます。
● 現実世界も「モノ(オブジェクト)」の組み合わせ
私たちの身の回りも、「モノ(=オブジェクト)」の組み合わせでできています。
- スマートフォン → データ:電話番号、アプリ / 処理:通話する、アプリを起動する
- 自動車 → データ:車種、スピード / 処理:走る、止まる
こうしたモノのように、データとそれに関係する動作を1つのかたまりとして扱うことで、より自然でわかりやすいプログラムが作れるようになります。
● ここから「オブジェクト指向」の世界へ
このような「データと処理をひとまとめにして部品にする」という考え方が、まさにオブジェクト指向の基本です。
次のセクションでは、具体的に「データと処理をまとめる」とはどういうことなのかを見ていきましょう。
2. 「データ」と「動作」をひとまとめにする¶
● 変数とメソッドがバラバラだと管理しづらい
たとえば、ゲームのキャラクターの情報を以下のように書いたとしましょう。
String name = "勇者";
int hp = 100;
public static void attack() {
System.out.println("勇者の攻撃!");
}
このように名前(データ)と攻撃する処理(動作)が別々に存在していると、たとえばキャラクターが複数いた場合にどの攻撃が誰のものか分かりづらくなってしまいます。
● クラスで「ひとまとめ」にする
Javaでは、「データ」と「動作」をクラスという仕組みで1つにまとめることができます。
public class Character {
String name;
int hp;
public void attack() {
System.out.println(name + "の攻撃!");
}
}
このように、変数(name, hp)とメソッド(attack)を一緒に定義することで、「この攻撃はこのキャラクターのもの」と明確にできます。
● 実際に使うときは「オブジェクト」として扱う
上のクラスをもとにして実際に使うには、次のようにオブジェクト(インスタンス)を作って使います。
Character hero = new Character();
hero.name = "勇者";
hero.hp = 100;
hero.attack(); // 勇者の攻撃!
これで、「勇者」というキャラクターの情報と、そのキャラクターがする動作を、自然な形でコードに表現できるようになりました。
● モノの「設計図」と「実体」
- Character クラス:モノの設計図
- hero インスタンス:実際のモノ(オブジェクト)
という関係です。この考え方が、今後のオブジェクト指向の中心になります。
● メソッドの使い方も変わってくる
メソッドも Character.attack() ではなく、hero.attack() のように、「誰が」その動作をするのかを表現できます。
これはまるで、「誰が何をするか」を命令しているようで、人間の感覚に近い設計が可能になるという利点があります。
3. 「世界」をオブジェクトで組み立てる¶
● オブジェクト=「役割を持った登場人物」
オブジェクト指向では、プログラムの構成要素をすべて「役割を持ったモノ(=オブジェクト)」として考えます。
たとえば、RPGゲームの世界を作るなら、次のような登場人物(オブジェクト)を考えることができます:
- 主人公(Player)
- 敵キャラ(Enemy)
- 回復アイテム(Potion)
- 戦闘シーンを管理する存在(BattleManager)
これらはすべて、それぞれ自分専用のデータとふるまい(メソッド)を持つ「オブジェクト」です。
● モノとモノがやりとりして世界が動く
たとえば、戦闘シーンでのやりとりは次のように考えられます:
- Player.attack(Enemy enemy):プレイヤーが敵を攻撃する
- Enemy.takeDamage(int damage):敵がダメージを受ける
- Potion.use(Player player):ポーションを使ってプレイヤーを回復する
こうして、オブジェクト同士がメッセージをやりとりするように処理が進むのがオブジェクト指向の世界です。
● たとえば「演劇」にたとえると…
オブジェクト指向の考え方は、舞台で演じる役者たちにたとえるとイメージしやすくなります:
舞台の世界 | プログラムの世界 |
---|---|
脚本(台本) | クラス(Class ) |
役者(演者) | オブジェクト(Object ) |
役者のセリフや動き | メソッド(Method ) |
舞台上の演技 | メッセージ(メソッド呼び出し) |
役者(オブジェクト)は、決まった台本(クラス)に基づいて動き、セリフ(メソッド)をしゃべったり、他の役者に話しかけたり(他のオブジェクトにメッセージを送ったり)します。
● 役割分担ができると、何がうれしいの?
- 処理が分かれていて、読みやすく・直しやすい
- 誰が何をするかがはっきりしていて、バグが起きにくい
- 登場人物を入れ替えても、他の部分を変えずに使い回せる
こうした特性は、大規模なプログラム開発やチーム開発で特に強みを発揮します。
4. 部品ごとに役割を分けると、いいことがある¶
プログラムを「部品の集合」として考えることができるようになると、たくさんのメリットが見えてきます。これは、オブジェクト指向が目指す世界の入口です。
● 修正がしやすくなる
たとえば、電卓の「引き算の処理」にバグがあったとします。
すべての処理が1つのクラスや1つのメソッドにまとまっていると、どこにその処理があるのか探しにくく、変更すると他の部分に影響が出るかもしれません。
しかし、「引き算」の処理が SubtractOperation クラスの calculate() メソッドにまとまっていれば、そのクラスだけを修正すれば済みます。
➡ 役割がはっきりしていれば、局所的な変更で済むのです。
● 再利用ができる
一度作った部品(クラスやメソッド)は、別のプログラムでも使い回すことができます。
たとえば、ボタンを押すと音が鳴る SoundButton クラスを作ったとしましょう。これをゲーム、教育アプリ、アラームアプリなど、まったく違う用途の中でも使えるのです。
➡ 汎用的な部品は、たくさんの場所で役立ちます。
● 他の人が作った部品も使える(ライブラリ、API)
自分で全部書かなくても、すでに誰かが作ってくれた部品を取り入れて開発できます。
- 日付や時間を扱う java.time パッケージ
- ファイルを読み書きする java.io パッケージ
- 数学計算のための java.math.BigDecimal
こうした「部品セット(ライブラリ)」をimportすることで、世界中の開発者が作った知恵を活用できます。
また、最近ではWebサービスとの連携も「API(Application Programming Interface)」という形で提供されています。APIも、外部の部品を利用する一種です。
● 実生活にたとえると…
現代の製品(スマートフォン、車、家電など)は、パーツごとに作られて組み立てられています。
バッテリーが壊れたら、バッテリーだけ交換すればいい。 音質を上げたければ、スピーカー部分だけ改良する。
同じように、プログラムも「役割ごとの部品」にしておくと扱いやすくなるのです。
5. プログラムを部品で「設計する」発想¶
オブジェクト指向では、「プログラムをいきなり書き始める」のではなく、どんな部品が必要か、どう組み合わせるかを考えてから作っていくのが基本です。これは建物を建てるときに設計図を書くのと同じです。
● 設計図を書く = クラスを考える
プログラムでいう「部品の設計図」は、クラス(class)です。
たとえば、自動販売機のプログラムを作る場合、次のようにクラスごとに役割を分けて考えます。
- Drink:飲み物の情報(名前・値段など)を管理する
- VendingMachine:在庫を持ち、お金の処理や購入処理を担当する
- Main:ユーザーの操作を受け取り、全体の流れを管理する
このように、どんな部品が必要かを事前に設計することで、後からの拡張や修正もやりやすくなります。
● クラス同士がどう関係するかを考える
部品(クラス)は、それぞれが独立しているだけでは意味がありません。どう関係し合うのかを考える必要があります。
たとえば:
- VendingMachine は Drink のリストを持つ(所有関係)
- Main クラスが VendingMachine のメソッドを呼び出す(操作関係)
こうしたクラス同士のつながりは、次の章で学ぶ「継承」「関連」「集約」「依存」といった関係の基礎になります。
● チーム開発や大規模開発ではこの発想が不可欠
個人で小さなプログラムを書くときは、設計をあまり意識しなくても動くものは作れます。
しかし、複数人で開発するときや、大きなシステムを作るときには、設計の有無が明暗を分けます。
- クラスごとの役割がはっきりしていれば、作業を分担しやすい
- 他人のコードの理解やレビューもしやすくなる
- 変更やバグ修正の影響範囲が小さくなる
➡ プログラムを「設計してから作る」ことは、実務でも非常に重要です。
● 実生活のメタファー
ソフトウェア開発も、家や製品をつくることと同じく「設計→部品→組み立て」の順で進めることで、失敗が少なくなります。
いきなり建材を積み上げて家を作る人はいません。まずは設計図を描くのです。
6. まとめ:オブジェクト指向とは「部品で考える」発想¶
これまでの内容で、オブジェクト指向の考え方の土台をざっくりとつかんでもらえたと思います。ここで一度、ポイントを振り返っておきましょう。
● 難しい文法の前に「考え方」が大事
オブジェクト指向というと、「クラス」「インスタンス」「継承」「多態性」などの専門用語や文法が注目されがちですが、それらはあくまで「道具」にすぎません。
もっと根本的な考え方は次の通りです:
Note
プログラムを、「意味のある部品」に分けて設計・組み立てること。
この「部品で考える」という発想こそが、オブジェクト指向の核です。
● メソッドは処理の部品、クラスはもっと大きな部品
前の章で学んだ「メソッド」も、処理の部品として活躍しました。でも、クラスはもっと大きな単位で、
- 状態(データ)
- 振る舞い(処理)
をセットで持ち、オブジェクトとして扱います。
これによって、「現実のものごと」をプログラムとして扱いやすくなるのです。
● オブジェクト指向は、整理された「設計」に向いている
- クラスごとに役割を分けることで、修正や拡張がしやすくなる
- 必要な部品を他のプログラムと共有・再利用できる
- 設計図を描くように、全体像を整理しやすい
そのため、大規模開発やチーム開発にはオブジェクト指向がよく使われます。
● 次章から:道具としての「クラス」や「インスタンス」を学ぶ
この章では、オブジェクト指向の「なぜ」や「考え方」を中心に学びました。
次からは実際に、
- クラスの作り方
- インスタンスの使い方
- メソッドやフィールドの使い分け
といった、具体的な使い方(= どうやって)を学んでいきます。
一言でまとめると…
オブジェクト指向とは、「プログラムを意味のある部品で組み立てよう」という発想。
7. 練習問題¶
○×問題(正しければ○、間違っていれば×で答えましょう)
①プログラムは、できるだけ1つの大きな部品にまとめた方がメンテナンスしやすい。
回答と解説(クリックして表示)
×
解説:プログラムは機能ごとに部品化し、役割を分けることで保守性が高まります。1つのクラスに全て詰め込むと、修正や再利用が難しくなります。
②オブジェクト指向では、「データ」と「そのデータを操作する処理」をひとまとまりにして扱う。
回答と解説(クリックして表示)
○
解説:オブジェクト指向の基本的な考え方のひとつです。データ(状態)と処理(振る舞い)をセットにすることで、現実世界の「モノ」に近い設計ができます。
③Javaでは、設計図としての「クラス」から、実際に動く「オブジェクト(インスタンス)」を作る。
回答と解説(クリックして表示)
○
解説:Javaでは、クラスがオブジェクトの設計図の役割を果たし、そのクラスを元にインスタンス(実体)を生成して利用します。
④オブジェクト指向では、他の人が作った部品(クラス)を再利用することはできない。
回答と解説(クリックして表示)
×
解説:むしろ、ライブラリやAPIなど、他の人が作った部品を再利用することがオブジェクト指向の大きなメリットの一つです。
⑤クラスを適切に分けておくと、修正や再利用がしやすくなる。
回答と解説(クリックして表示)
○
解説:各クラスに責任を分担させることで、必要な変更だけを行えばよくなり、保守性と再利用性が向上します。