オブジェクト指向とは?
継承・オーバーライド・集約をコードで理解する
この問題の答えはイ「サブクラスではスーパークラスの操作を再定義できる」。これを暗記する前に、「なぜそれが可能なのか」を理解しましょう。
結局、オブジェクト指向とは何か?
オブジェクト指向とは、システムを「データ(状態)」と「そのデータに対する操作(振る舞い)」を持つもの同士の組合せとして設計する考え方です。現実の「銀行口座」は残高というデータを持ち、入金や出金ができます。このまとまりをプログラムで表現します。
銀行口座は「残高を持ち、入金・出金できる」と定義する。
Aさんの残高10万円の口座、Bさんの残高3万円の口座。
クラスは共通の仕組みを定義し、各インスタンスはそれぞれ固有の状態を持ちます。
継承:「共通する仕組み」を引き継ぐ
たとえば通知システムで「通知」という共通クラスを作り、「メール通知」「SMS通知」を派生させるとします。通知の送信先や共通ログ処理は親クラスにまとめ、送信方法だけ子クラスごとに変えられます。
スーパークラス=親クラス/基底クラス、サブクラス=子クラス/派生クラスとも呼びます。継承は「〜の一種である(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)のです。これは継承ではなく、集約・コンポジションなどの全体と部分の関係で表します。
親クラスの操作を引き継げる。
部品の操作や属性を継承するわけではない。
UMLでは集約は白いひし形、コンポジションは黒いひし形で表すのが一般的です。コンポジションは部品の寿命が全体に強く依存する関係を表します。
操作ラボ:どのメソッドが実行される?
下のラボでインスタンスの種類と呼び出す操作を切り替えてください。「子クラスが親の操作を再定義したとき」と「親の操作をそのまま使うとき」の違いが分かります。
メソッド呼び出し実験
ボタンを変えると、実際に呼ばれるメソッドが変わります。
子クラスのインスタンス自身が、上書きした send() を実行します。親の別インスタンスへ依頼しません。
過去問の4択を根拠から判定
セキスペ対策としての補足
セキュリティ設計でも、共通の認証・認可処理をどこに置くかは重要です。継承先でメソッドが再定義されると、親クラスで想定した検証処理が実行されなくなる場合があります。オーバーライドした操作にも必要な認可チェックがあるか、テストで確認しましょう。