本日は、継承の基本とインタフェースの理解を深めることをテーマに問題を解いていきましょう。
問題
以下のプログラムを実行した場合の出力として正しいものを選択してください。
interface Food {
void consume();
}
abstract class Fruit implements Food {
@Override
public void consume() {
System.out.println("Consuming fruit");
}
}
class Apple extends Fruit {
public void sweet() {
System.out.println("This apple is sweet.");
}
}
public class Main {
public static void main(String[] args) {
Food myFood = new Apple();
myFood.consume();
}
}
選択肢
- A. Consuming fruit
- B. This apple is sweet.
- C. コンパイルエラー
- D. 実行時エラー
答えと解説
回答を見る
答え
A. Consuming fruit
解説
基本説明:
この問題ではインタフェース、抽象クラス、具象クラスの関係を理解する必要があります。
Food
はインターフェースであり、Fruit
は抽象クラスとしてそれを実装しています。
さらにApple
は具体的な具象クラスであり、Fruit
を継承しています。
メインメソッドでは、Apple
オブジェクトをFood
型の変数に格納しているため、
インタフェース型で定義されたconsume
メソッドを呼び出しています。
結果として、Fruit
クラスでオーバーライドされているconsume
メソッドが実行されます。
誤答理由:
「B. This apple is sweet.」と期待した場合、sweet
メソッドを直接呼び出す必要があります。
しかし、Food
型の変数ではsweet
メソッドはアクセスできません。
「C. コンパイルエラー」と「D. 実行時エラー」については、 型付けやメソッド呼び出しの形式自体に問題はありません。したがって出力は正常に行われます。
つまずきポイント:
初心者が迷う点として、インタフェース型の変数が具象クラスのインスタンスを保持した際に、 何が呼び出せるのかが挙げられます。 インタフェース型で保持されている場合、そのインタフェースで定義されているメソッドしか直接呼び出せません。
発展知識:
Javaのインターフェースは、クラスが必ず実装すべきメソッドのセットを定義します。 これにより、特定の動作契約をクラスに課すことができます。
抽象クラスを使用する理由として、共通のコードを繰り返し記述せずに済むこと、 つまりコードの再利用性を向上させることができます。