7章14

TANIAOKA, Akihiro - Apr 8 - - Dev Community

この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メソッドを継承している。
    }
}
Enter fullscreen mode Exit fullscreen mode

解答 A「Mainクラスの6行目でコンパイルエラーが発生する」が正しい理由は、変数 aWorker インターフェースの型で宣言されており、Worker インターフェースには create() メソッドが定義されていないためです。Javaでは、参照変数の型が持っているメソッドのみを呼び出せます。したがって、Worker 型の acreate() メソッドを呼び出そうとすると、コンパイラはそのメソッドを Worker インターフェース内で見つけられず、エラーを出します。

Bは正しくない理由は、b.work();Employee クラスの work() メソッドを正しく呼び出すため、エラーにはなりません。Cは正しくない理由は、bEmployee 型であり、create() メソッドは Engineer クラスにしか存在しないため、Employee 型の b では create() メソッドを呼び出すことができません。Eは report() メソッドが Employee クラスに存在し、Engineer クラスがこれを継承しているため正しく実行できます。

追記

もし Worker インターフェースに create() メソッドが定義されていれば、a.create() を呼び出す際にコンパイルエラーは発生しません。以下のように Worker インターフェースを変更して create() メソッドを定義することができます:

public interface Worker {
    void work();
    void create(); // createメソッドをインターフェースに追加
}
Enter fullscreen mode Exit fullscreen mode

この変更を加えた後、Engineer クラスは Worker インターフェースから create() メソッドも実装しなければなりません。ただし、既に Engineer クラスには create() メソッドの実装があるので、これ以上の変更は不要です。その結果、Worker 型の参照変数である a でも create() メソッドを呼び出せるようになり、エラーは解消されます。

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .