株式会社ジオデータ開発 ロゴ
株式会社ジオデータ開発GEO DATA DEVELOPMENT Inc.
オブジェクト指向

オブジェクト指向とは?
継承・オーバーライド・集約をコードで理解する

この問題の答えはイ「サブクラスではスーパークラスの操作を再定義できる」。これを暗記する前に、「なぜそれが可能なのか」を理解しましょう。

結局、オブジェクト指向とは何か?

オブジェクト指向とは、システムを「データ(状態)」と「そのデータに対する操作(振る舞い)」を持つもの同士の組合せとして設計する考え方です。現実の「銀行口座」は残高というデータを持ち、入金や出金ができます。このまとまりをプログラムで表現します。

クラス=設計図

銀行口座は「残高を持ち、入金・出金できる」と定義する。

インスタンス=実体

Aさんの残高10万円の口座、Bさんの残高3万円の口座。

クラスは共通の仕組みを定義し、各インスタンスはそれぞれ固有の状態を持ちます。

継承:「共通する仕組み」を引き継ぐ

たとえば通知システムで「通知」という共通クラスを作り、「メール通知」「SMS通知」を派生させるとします。通知の送信先や共通ログ処理は親クラスにまとめ、送信方法だけ子クラスごとに変えられます。

通知(スーパークラス)
send() / log()
↓ 継承する
メール通知
send() を再定義
SMS通知
send() を再定義

スーパークラス=親クラス/基底クラス、サブクラス=子クラス/派生クラスとも呼びます。継承は「〜の一種である(is-a)」関係です。

オーバーライド:「親の操作」を子が再定義する

「通知を送る」という操作名は共通でも、メールとSMSでは実際の送信処理が異なります。親クラスから継承したメソッドを子クラスで再定義する仕組みがオーバーライド(override)です。

class Notification {
  send() { return "通知を送信"; }
  log() { return "送信履歴を記録"; }
}
class EmailNotification extends Notification {
  send() { return "メールを送信"; }
}
const item = new EmailNotification();
item.send(); // "メールを送信"
item.log();  // "送信履歴を記録"
試験の正解がイである理由:サブクラスは親の操作を継承できますが、同名の操作を自分で定義し直すこともできます。親が別の「インスタンス」として存在して、毎回そこへ処理を依頼するわけではありません。

ただし、言語によって継承やオーバーライドに制約があります。たとえば再定義できないメソッドもあります。「すべてのメソッドが無条件に再定義可能」という意味ではありません。

集約:『一種』ではなく『全体と部品』

車とエンジンの関係を考えます。「車はエンジンの一種」ではありません。車はエンジンを部品として持っている(has-a)のです。これは継承ではなく、集約・コンポジションなどの全体と部分の関係で表します。

継承(is-a)
メール通知 は 通知の一種

親クラスの操作を引き継げる。

集約(has-a)
車 は エンジンを持つ

部品の操作や属性を継承するわけではない。

UMLでは集約は白いひし形、コンポジションは黒いひし形で表すのが一般的です。コンポジションは部品の寿命が全体に強く依存する関係を表します。

操作ラボ:どのメソッドが実行される?

下のラボでインスタンスの種類と呼び出す操作を切り替えてください。「子クラスが親の操作を再定義したとき」と「親の操作をそのまま使うとき」の違いが分かります。

メソッド呼び出し実験

ボタンを変えると、実際に呼ばれるメソッドが変わります。

① どのインスタンス?
② 何の操作を呼ぶ?
呼び出し
instance.send()
実行結果
メールを送信
実行元:子クラスが再定義した send()

子クラスのインスタンス自身が、上書きした send() を実行します。親の別インスタンスへ依頼しません。

過去問の4択を根拠から判定

ア:誤り ― クラスの関連は2クラス間だけとは限りません。3つ以上のクラスを関連付ける多項関連も表現できます。また1つのクラスは複数の相手と関連できます。
イ:正解 ― 子クラスが親クラスのメソッドをオーバーライドできます。
ウ:誤り ― 親クラスの操作を継承した子インスタンスは、親の別インスタンスに依頼せずに操作を実行できます。必要ならコードで親側の実装を呼び出すことはできますが、別インスタンスへの依頼ではありません。
エ:誤り ― 集約は全体と部分の関係であり、部品の属性・操作を継承して共有する関係ではありません。

セキスペ対策としての補足

セキュリティ設計でも、共通の認証・認可処理をどこに置くかは重要です。継承先でメソッドが再定義されると、親クラスで想定した検証処理が実行されなくなる場合があります。オーバーライドした操作にも必要な認可チェックがあるか、テストで確認しましょう。

要点:「オーバーライド=親の操作を子で上書き」「継承=is-a」「集約=has-a」。似た用語を暗記するより、実際に操作がどこで実行されるかを追うと整理できます。