DEV Community

TANIAOKA, Akihiro
TANIAOKA, Akihiro

Posted on

7章16

このJavaのコードは、クラスの継承とオブジェクトの型変換に関する問題です。問題は、あるクラスのオブジェクトを別のクラスの変数に割り当てる際にどのような記述が正しいかを尋ねています。クラスABがあり、BAを継承しています。Bにはhelloメソッドがあります。

メインメソッド内で、BのインスタンスをAの型で宣言された変数aに割り当てています。問題は、このインスタンスをBの型で宣言された新しい変数bにどう割り当てるかです。

答えがF、すなわち B b = (B) a;である理由を説明します。

  1. A a = new B();BのインスタンスをA型の変数に代入しており、アップキャストと言います。Javaでは、子クラスのインスタンスは常に親クラスの型に自動的に変換されるため、特にキャストする必要はありません。

  2. b.hello(); の行でBhelloメソッドを呼び出していますが、変数aAの型で宣言されているため、A型にはhelloメソッドが存在しないため、このままではメソッドを呼び出せません。

  3. そのため、B型のメソッドを呼び出すには、aB型にダウンキャストする必要があります。ダウンキャストは、親クラスの型から子クラスの型への変換を指し、明示的にキャストを行う必要があります。

  4. Fの選択肢 B b = (B) a; は、aが実際にはBのインスタンスであることを示し、B型にダウンキャストしています。これにより、B型として変数bを宣言し、Bに定義されているhelloメソッドを呼び出せるようになります。

他の選択肢が不適切な理由:

  • A (A b = a;) では、型がAであるためhelloメソッドを呼び出せません。
  • B (A b = new B();) では新しいインスタンスを作成しており、既存の変数aとは無関係です。
  • C (A b = (A) a;) は不要なアップキャストをしています。
  • D (B b = a;) ではキャストがないため、コンパイルエラーになります。
  • E (B b = (A) a;) は間違ったキャストを行っており、A型をB型に変換しようとしていますが、aは既にA型です。

追記

了解しました。設問の空欄にFの選択肢 B b = (B) a; が正しい理由を説明するコメントをコードに追加します。

// クラスAは何も内容が定義されていない空のクラスです。
class A { }

// クラスBはクラスAを継承しており、helloメソッドを持っています。
class B extends A {
    // helloメソッドは画面に"hello"と出力します。
    void hello() {
        System.out.println("hello");
    }
}

// メインクラスとそのメインメソッドです。プログラムの実行はここから始まります。
public class Main {
    public static void main(String[] args) {
        // A型の変数aを宣言し、Bクラスのインスタンスを割り当てます。
        // ここでの代入はアップキャストとして自動的に行われます。
        // アップキャストは、子クラスのインスタンスを親クラスの型の変数に割り当てる操作です。
        A a = new B();

        // この時点では、変数aはA型として宣言されているので、Bクラスのhelloメソッドを直接呼び出すことはできません。
        // A型にはhelloメソッドが定義されていないからです。

        // したがって、Bのインスタンスとして宣言された変数aのhelloメソッドを呼び出すには、
        // aをB型にダウンキャストする必要があります。
        // ダウンキャストは、親クラスの型から子クラスの型への明示的な型変換です。

        // 空欄には、以下のコード行が適切です。
        B b = (B) a; // 変数aをB型にダウンキャストして、B型の変数bに代入します。

        // これでbを通じてBクラスのhelloメソッドを安全に呼び出すことができます。
        b.hello();
    }
}
Enter fullscreen mode Exit fullscreen mode

上記のコードには、B b = (B) a; という行が含まれており、これは親クラス型(A型)の変数aを子クラス型(B型)にキャストして新しいB型の変数bに代入しています。このキャストは必須で、実際にはBのインスタンスであることをコンパイラに伝えるために使われます。そしてbBのインスタンスであることが保証された上で、Bに定義されたhelloメソッドを呼び出すことができます。

Top comments (0)