基本情報技術者 2017年 秋期 午前(科目A) 問07
問題文
オブジェクト指向プログラミングにおける、多相性を実現するためのオーバーライドの説明はどれか。
選択肢
ア:オブジェクト内の詳細な仕様や構造を外部から隠蔽すること
イ:スーパークラスで定義されたメソッドをサブクラスで再定義すること(正解)
ウ:同一クラス内に、メソッド名が同一で、引数の型、個数、並び順が異なる複数のメソッドを定義すること
エ:複数のクラスの共通する性質をまとめて、抽象化したクラスを作ること
オーバーライドの説明【午前2 解説】
要点まとめ
- 結論:オーバーライドとは、スーパークラスで定義されたメソッドをサブクラスで同一シグネチャで再定義して多相性を実現する手法です。
- 根拠:同一シグネチャのメソッドをサブクラスが置き換えると、実行時に参照の実際の型に応じた実装が呼ばれ動的結合(ランタイムポリモーフィズム)になります。
- 差がつくポイント:シグネチャの一致、戻り値の共変、アクセス制限の緩和不可、言語ごとの仮想メソッド扱い(例:Javaは基本的に仮想、C++はvirtualが必要)を押さえておきましょう。
正解の理由
正解: イ
オーバーライドは「スーパークラスで定義されたメソッドをサブクラスで再定義すること」です。これにより、スーパークラス型の変数であっても、実行時にサブクラスの実装が呼ばれ、異なる振る舞いを同一インタフェースで扱えるため多相性(ポリモーフィズム)が実現されます。問題文の選択肢イはこの定義に正確に一致します。
オーバーライドは「スーパークラスで定義されたメソッドをサブクラスで再定義すること」です。これにより、スーパークラス型の変数であっても、実行時にサブクラスの実装が呼ばれ、異なる振る舞いを同一インタフェースで扱えるため多相性(ポリモーフィズム)が実現されます。問題文の選択肢イはこの定義に正確に一致します。
よくある誤解
- 「引数の異なる同名メソッドはオーバーライドだ」と誤認する人が多いですが、これはオーバーロード(多重定義)でありオーバーライドではありません。
- 「アクセス修飾子を狭くしても問題ない」と考える誤り。サブクラスでの再定義は元よりアクセスを狭めることはできず、可視性は維持または緩和する必要があります。
- 「全ての言語で同じ挙動」と捉えるのも危険です。言語ごとに仮想メソッドの扱いやルール(final/static/private の扱い)が異なります。
解法ステップ
- 問題文のキーワードを抽出:「多相性」「オーバーライド」。
- 各選択肢の定義を確認:オーバーライド=スーパークラスのメソッドをサブクラスで再定義。
- 選択肢の文言とオーバーライドの要件(同一シグネチャ、実行時結合)を照合。
- オーバーロードや抽象化など他の概念と混同していないかをチェックして絞り込む。
- 正しい選択肢(イ)を選択する。
選択肢別の誤答解説
- ア: オブジェクト内の詳細な仕様や構造を外部から隠蔽すること
- これは「カプセル化(情報隠蔽)」の説明であり、オーバーライドとは無関係です。
- イ: スーパークラスで定義されたメソッドをサブクラスで再定義すること
- 正解。オーバーライドの定義に合致します。サブクラスで同一シグネチャの実装を上書きし、実行時に適切なメソッドが選ばれます。
- ウ: 同一クラス内に、メソッド名が同一で、引数の型、個数、並び順が異なる複数のメソッドを定義すること
- これは「オーバーロード(メソッドの多重定義)」の説明です。コンパイル時にどのメソッドが呼ばれるか決まります。
- エ: 複数のクラスの共通する性質をまとめて、抽象化したクラスを作ること
- これは「抽象化」や「抽象クラスの作成」に関する説明であり、オーバーライドそのものの定義ではありません(抽象メソッドをサブクラスで実装することはオーバーライドの一例ですが、設問の説明としては不一致です)。
補足コラム
- オーバーライドとオーバーロードの違い(短い例)
- オーバーライド:親クラスにあるメソッドと同じシグネチャでサブクラスが再定義。実行時にどの実装を呼ぶかが決まる。
- オーバーロード:同一クラス内でメソッド名は同じだが引数リストを変えて複数定義。コンパイル時に呼び出し候補が決定される。
- 実装例(Java):
class Animal {
void speak() { System.out.println("..."); }
}
class Dog extends Animal {
@Override
void speak() { System.out.println("ワン"); } // オーバーライド
void speak(String mood) { System.out.println("ワン:" + mood); } // オーバーロード
}
- 言語差:C++ではvirtual修飾子がないと動的結合されない点、Javaでは通常メソッドが仮想(final/静的/privateは例外)である点に注意してください。
- Liskov置換原則(LSP):サブクラスはスーパークラスの代替となるべき、オーバーライド実装はこの原則に従うべきです(前提条件は弱く、事後条件は強くしないなど)。
FAQ
Q1: オーバーライドするための条件は何ですか?
A1: メソッド名、引数の型と順序(シグネチャ)が同一であること。戻り値は共変が許される言語もあります。アクセスは狭められない点も注意。
A1: メソッド名、引数の型と順序(シグネチャ)が同一であること。戻り値は共変が許される言語もあります。アクセスは狭められない点も注意。
Q2: オーバーライドとオーバーロードはどこで見分ける?
A2: 引数リストが異なればオーバーロード、同一でサブクラスで再定義しているならオーバーライドです。多相性を引き起こすのはオーバーライドです。
A2: 引数リストが異なればオーバーロード、同一でサブクラスで再定義しているならオーバーライドです。多相性を引き起こすのはオーバーライドです。
Q3: static メソッドや private メソッドはオーバーライドできますか?
A3: static はクラスに紐づくためオーバーライドされず、private はサブクラスから見えないためオーバーライド扱いになりません。言語仕様を確認してください。
A3: static はクラスに紐づくためオーバーライドされず、private はサブクラスから見えないためオーバーライド扱いになりません。言語仕様を確認してください。
Q4: 戻り値の型が異なっていてもオーバーライドは可能ですか?
A4: 一部言語では「共変戻り値型」を許容します(サブクラスの型を返すことが可能)が、完全に異なる型は基本的に不可です。
A4: 一部言語では「共変戻り値型」を許容します(サブクラスの型を返すことが可能)が、完全に異なる型は基本的に不可です。
関連キーワード: オブジェクト指向、多相性、ポリモーフィズム、オーバーライド、オーバーロード、継承、仮想メソッド、抽象化、Liskov置換原則、動的結合

\ せっかくなら /
基本情報技術者を
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

