このJavaのコードは、ポリモーフィズムと継承の概念を使っています。ポリモーフィズムとは、サブクラスのオブジェクトがスーパークラスの型で参照されることができる、というオブジェクト指向プログラミングの特徴です。以下のコードにコメントアウトを加えることで、それぞれのステートメントが何を意味するのかを説明します。
// Workerインターフェース定義。workメソッドが必要。
public interface Worker {
void work();
}
// EmployeeクラスはWorkerインターフェースを実装する。workとreportメソッドを持つ。
class Employee implements Worker {
public void work() {
System.out.println("work");
}
public void report() {
System.out.println("report");
}
}
// EngineerクラスはEmployeeクラスを継承する。createメソッドを新たに追加。
class Engineer extends Employee {
public void create() {
System.out.println("create future");
}
}
// メインクラスとメインメソッド。
public class Main {
public static void main(String[] args) {
Worker a = new Engineer(); // EngineerオブジェクトをWorker型でインスタンス化。
Employee b = new Engineer(); // EngineerオブジェクトをEmployee型でインスタンス化。
Engineer c = new Engineer(); // EngineerオブジェクトをEngineer型でインスタンス化。
a.create(); // コンパイルエラー。Worker型の参照変数はcreateメソッドを知らない。
b.work(); // 正常に動作。Employeeはworkメソッドを継承している。
c.report(); // 正常に動作。EngineerはEmployeeからreportメソッドを継承している。
}
}
解答 A「Mainクラスの6行目でコンパイルエラーが発生する」が正しい理由は、変数 a が Worker インターフェースの型で宣言されており、Worker インターフェースには create() メソッドが定義されていないためです。Javaでは、参照変数の型が持っているメソッドのみを呼び出せます。したがって、Worker 型の a で create() メソッドを呼び出そうとすると、コンパイラはそのメソッドを Worker インターフェース内で見つけられず、エラーを出します。
Bは正しくない理由は、b.work(); は Employee クラスの work() メソッドを正しく呼び出すため、エラーにはなりません。Cは正しくない理由は、b は Employee 型であり、create() メソッドは Engineer クラスにしか存在しないため、Employee 型の b では create() メソッドを呼び出すことができません。Eは report() メソッドが Employee クラスに存在し、Engineer クラスがこれを継承しているため正しく実行できます。
追記
もし Worker インターフェースに create() メソッドが定義されていれば、a.create() を呼び出す際にコンパイルエラーは発生しません。以下のように Worker インターフェースを変更して create() メソッドを定義することができます:
public interface Worker {
void work();
void create(); // createメソッドをインターフェースに追加
}
この変更を加えた後、Engineer クラスは Worker インターフェースから create() メソッドも実装しなければなりません。ただし、既に Engineer クラスには create() メソッドの実装があるので、これ以上の変更は不要です。その結果、Worker 型の参照変数である a でも create() メソッドを呼び出せるようになり、エラーは解消されます。
Top comments (0)