Java构造器练习题
仔细阅读下面的程序
public class Car {
String name = "汽车";
public Car(String name) {
this.name = name;
}
// 加上main方法
public static void main(String[] args) {
Car bmw = new BMW("宝马X5");
System.out.println(bmw.name);
}
}
class BMW extends Car {
String name = "宝马";
public BMW(String name) {
this.name = name;
}
}
请问正确的选项是什么?
A.汽车 B.宝马 C.宝马x5 D.编译报错 E.输出异常
答案
答案是:D.编译报错
解析
1.相关知识
子类继承父类时,如果父类没有无参构造器,子类需要在构造函数中通过super(参数),先显示调用父类的有参构造。
2.代码流程
- 定义了Car类,包含name属性值为"汽车";
- 定义了有参构造将默认的name值"汽车"传递给参数;
- 定义了BMW类继承Car类,包含name属性值为"宝马";
- 有参构造将name属性值设为传递进来的参数值;
- Car类中的main方法中,声明了一个Car对象,new一个BMW实例,输出实例的name属性值。
3.答案解析
情况一:在父类中添上无参构造,输出汽车
因为父类没有给出无参构造,子类必须要显示调用父类的有参构造,因此会发生编译错误。如果显示调用了父类的有参构造,则调用的是父类的name值,但由于赋值语句是将原值赋值给参数,因此"汽车"并未发生改变,会输出"汽车"。代码如下:
public class Car {
String name = "汽车";
public Car(String name) {
this.name = name;
}
// 加上无参构造
public Car() {}
// 加上main方法
public static void main(String[] args) {
Car bmw = new BMW("宝马X5");
System.out.println(bmw.name);
}
}
class BMW extends Car {
String name = "宝马";
public BMW(String name) {
this.name = name;
}
}
情况二:在子类中显示调用父类有参构造,输出宝马X5
public class Car {
String name = "汽车";
public Car(String name) {
this.name = name;
}
// 加上main方法
public static void main(String[] args) {
Car bmw = new BMW("宝马X5");
System.out.println(bmw.name);
}
}
class BMW extends Car {
String name = "宝马";
public BMW(String name) {
// 显示调用父类有参构造器
super(name);
this.name = name;
}
}