このJavaのコードは、継承に関する問題です。Parentクラスがあり、それを継承するChildクラスが定義されています。両クラスにはnameというフィールドがあり、Parentクラスにはnameフィールドを返すgetName()メソッドがあります。
MainクラスではChildクラスのインスタンスを作成し、nameフィールドに"sample"を設定してから、そのnameを取得して表示しようとしています。
ここでの重要なポイントは、ChildクラスがParentクラスのnameフィールドを隠蔽していることです。Childのインスタンスでnameにアクセスすると、Childクラスのnameが使われますが、getName()メソッドはParentクラスに定義されており、this.nameとしてParentクラスのnameフィールドを参照します。しかし、Childクラスのコンストラクタを通じてnameが初期化されないため、Parentクラスのnameフィールドはnullのままです。
結果として、System.out.println(child.getName());はParentクラスのnameフィールドの値を表示しようとしますが、それはnullのままなので、出力は[null]となります。
したがって、選択肢の中で正しい答えは B. [null] と表示される です。
以下はコメントを加えたコードです。
// Parentクラス定義
class Parent {
String name; // Parentクラスのnameフィールド
String getName() { // Parentクラスのnameフィールドを返すメソッド
return this.name; // thisはParentクラスのインスタンスを指す
}
}
// ChildクラスはParentクラスを継承
public class Child extends Parent {
String name; // Childクラスもnameフィールドを持っている(Parentクラスのnameフィールドを隠蔽)
}
// メインクラス
public class Main {
public static void main(String[] args) {
Child child = new Child(); // Childクラスのインスタンスを作成
child.name = "sample"; // Childクラスのnameフィールドに"sample"を設定
// getName()メソッドを呼び出すと、Parentクラスのnameフィールドの値(null)が返される
System.out.println(child.getName());
}
}
追記
"sample"を出力させるためには、以下のいずれかの方法でParentクラスのname変数を設定する必要がある
- コンストラクタを通じて
nameを設定する。 -
setNameメソッドをParentクラスに追加して、そのメソッドを使ってnameを設定する。 -
Childクラスでname変数を宣言せず、代わりに継承されたname変数に直接値を設定する。
具体的には、以下のような変更を行います:
class Parent {
String name;
String getName() {
return this.name;
}
void setName(String name) {
this.name = name;
}
}
public class Child extends Parent {
// 'String name;' を削除
}
public class Main {
public static void main(String[] args) {
Child child = new Child();
// child.name = "sample"; を変更
child.setName("sample");
System.out.println(child.getName());
}
}
Childクラスのname宣言を削除し、Parentクラスのname変数に直接アクセスしています。また、setNameメソッドをParentクラスに追加し、このメソッドを使ってnameの値を設定しています。これで"sample"という文字列が出力されるようになります。
補足
設問で見られる問題は、ParentクラスとChildクラスの両方にnameというフィールドが存在している点です。Javaでは、サブクラスがスーパークラスと同じ名前のフィールドを持つとき、サブクラスのフィールドがスーパークラスのフィールドを「隠蔽」します。これをフィールドのシャドーイングと言います。
このコードにおいてChildクラスのオブジェクトを作成し、Childクラスのnameフィールドに"sample"という値を設定します。しかし、getName()メソッドはParentクラスに定義されており、このメソッドはParentクラスのnameフィールドの値を返します。Parentクラスのnameフィールドは初期化されていないため、nullが返されます。
つまり、child.name = "sample";というコード行はChildクラスのnameフィールドに"sample"を設定しますが、child.getName()はParentクラスのgetName()メソッドを呼び出し、これはParentクラスのnameフィールドの値を返すため、結果としてnullが表示されます。
Top comments (0)