Javaの基礎をしっかりと理解しましょう。Javaテクノロジと開発環境に関する問題を解きます。
問題
次のプログラムを実行した場合の出力はどれになるでしょうか?正しい選択肢を選んでください。
class Device {
String type = "Unknown device";
String getDeviceType() {
return type;
}
}
class Computer extends Device {
String type = "Computer";
@Override
String getDeviceType() {
return type;
}
}
public class Main {
public static void main(String[] args) {
Device myDevice = new Computer();
System.out.println(myDevice.type);
}
}
選択肢
- A. Computer
- B. Unknown device
- C. コンパイルエラー
- D. 実行時エラー
答えと解説
回答を見る
答え
B. Unknown device
解説
基本説明: 変数のシャドーイング(shadowing)に関する問題です。
このプログラムではDevice
クラスとComputer
クラスがあります。Computer
はDevice
を継承していますが、type
というメンバー変数を再度定義しています。
Main
クラスのmain
メソッドではDevice
型のmyDevice
変数を使っています。この変数はComputer
クラスのインスタンスです。
しかし、変数myDevice
が参照するのはDevice
型としてのインスタンスです。変数の再定義は静的には隠蔽される(シャドーイングされる)ため、Device
クラスのtype
が参照され「Unknown device」と出力されます。
誤答理由: オーバーライドとシャドーイングの混同
オーバーライドされたメソッドは常に実際のオブジェクトタイプに基づいて実行されますが、メンバー変数は変数の型に基づいて参照されます。
この違いを理解せずに選択肢A「Computer」を選ぶ誤りはここから来ています。オーバーライドを過信せず変数のシャドーイングも意識する必要があります。
つまずきポイント: シャドーイングを見逃しがち
変数の影響範囲(スコープ)の理解が不足しがちな点です。特に、this
を使わないとオブジェクトの基になるクラスの変数が参照されるため注意が必要です。
この問題から学べるのは、クラス継承における変数のシャドーイングに対する注意が必要ということです。
発展知識: 継承とシャドーイング
継承時のメソッドと変数の扱いは異なるため、クラス設計時には両者を混同しないことが大切です。
特に、データの隠蔽を強く意識しないと、コードのメンテナンス性が低下しやすいです。super
キーワードを使うと上位クラスの変数にアクセスすることができます。
この習得ポイントを意識することで、Javaの開発環境の中でもより効率的で理解しやすいコードを書くことができるようになります。