
問題
次のコードをコンパイル、実行するとどうなりますか。
public class Main {
public static void main(String... args) {
Person p1 = new Person();
AbstractPerson a1 = new Person();
Person p2 = new Person("Duke");
AbstractPerson a2 = new Person("Scott");
p1.print();
p2.print();
a1.print();
a2.print();
}
}
abstract class AbstractPerson {
String name;
AbstractPerson() {
this.name = "Ace";
}
AbstractPerson(String name) {
this.name = name;
}
public void print() {
System.out.print(" print:" + name);
}
abstract void print(String name);
}
class Person extends AbstractPerson {
String name;
Person() {
this.name = "King";
}
Person(String name) {
this.name = name;
}
public void print(String name) {
System.out.print(" print:" + name);
}
}
選択肢
A)print:null print:null print:Ace print:Ace が出力される
B)print:Ace print:Ace print:Ace print:Ace が出力される
C)NullPointerException がスローされる
D)コンパイルエラーになる
E)print: print: print:Ace print:Scott が出力される
F)print:King print:Duke print:Ace print:Scott が出力される
G)print:King print:Duke print:Ace print:Ace が出力される
解答
A)print:null print:null print:Ace print:Ace が出力される
B)print:Ace print:Ace print:Ace print:Ace が出力される
C)NullPointerException がスローされる
D)コンパイルエラーになる
E)print: print: print:Ace print:Scott が出力される
F)print:King print:Duke print:Ace print:Scott が出力される
G)print:King print:Duke print:Ace print:Ace が出力される
解説
コンストラクタの動作
Person p1 = new Person();Personのデフォルトコンストラクタが呼び出されます。この時、nameは"King"に設定されますが、スーパークラスAbstractPersonのコンストラクタも呼び出され、this.name(スーパークラスのname)が"Ace"に設定されます。したがって、p1のAbstractPersonにおけるnameは"Ace"です。
AbstractPerson a1 = new Person();- 同じように、
Personのデフォルトコンストラクタが呼び出され、a1のAbstractPersonにおけるnameも"Ace"です。
- 同じように、
Person p2 = new Person("Duke");- この場合、
nameは"Duke"に設定されますが、AbstractPersonのnameは変更されず、依然として"Ace"です。
- この場合、
AbstractPerson a2 = new Person("Scott");a2に対しても同様の処理が行われ、nameは"Scott"に設定されますが、スーパークラスのnameは"Ace"です。
print メソッドの呼び出し
p1.print();printメソッドはAbstractPersonから呼ばれます。ここでnameは"Ace"なので、出力はprint:Aceになります。
p2.print();- 同様に、
p2もAbstractPersonのprintメソッドを呼び出し、nameは"Ace"です。したがって、出力はprint:Aceになります。
- 同様に、
a1.print();a1も同様にAbstractPersonのprintメソッドを呼び出し、出力はprint:Aceになります。
a2.print();- 最後に、
a2も同様にAbstractPersonのprintメソッドを呼び出し、出力はprint:Aceになります。
- 最後に、
結論
最終的に、すべての print 呼び出しが AbstractPerson の name("Ace")を参照するため、出力は次のようになります:
print:Ace print:Ace print:Ace print:Ace
対象資格:Java SE17 認定資格
