因为有继承关系存在时子类需要把父类的属性继承下来。所以在执行子类的构造方法的过程中,必须先调用其父类的构造方法。
看如下代码:
public class Father {
protected String firstName = "张";
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
Father(){
System.out.println("Father Constructor is run...");
}
}
public class Son extends Father {
Son(){
//super(); //这里隐含着去调用了父类默认无参数的构造方法。
System.out.println("Son Constructor is run...");
}
}
public class Test {
public static void main(String[] args) {
Son s = new Son();
System.out.println(s.getFirstName());
}
}
运行结果:
Father Constructor is run...
Son Constructor is run...
张
结论:执行子类子类构造方法时,第一句话总是默认先去调用父类无参数的构造方法,如果父类没有默认无参数的构造方法,则需要显示调用父类带参数的构造方法,以完成父类属性的初始化。
我们知道子类重写从父类继承过来的方法称为方法重写,那么子类是不能重写从父类继承过来的属性,但是子类可以覆盖父类的属性。
例如以下代码:
public class Father {
protected String firstName = "张";
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
Father(){
System.out.println("Father Constructor is run...");
}
}
public class Son extends Father {
String firstName = "李"; //这里出现了属性覆盖。
@Override
public String getFirstName() {
return firstName;
}
@Override
public void setFirstName(String firstName) {
this.firstName = firstName;
}
Son(){
//super(); //这里隐含着去调用了父类默认无参数的构造方法。
System.out.println("Son Constructor is run...");
}
}
public class Test {
public static void main(String[] args) {
Son s = new Son();
System.out.println(s.getFirstName());
}
}
运行结果:
Father Constructor is run...
Son Constructor is run...
李
在Java中super有两种使用场景。1.调用父类的构造方法。2.调用父类的属性和方法。
1)调用父类的构造方法。
public class Father {
protected String firstName ;
Father(String firstName){
this.firstName = firstName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
}
public class Son extends Father {
String firstName = "李";
@Override
public String getFirstName() {
return firstName;
}
@Override
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public Son(String firstName,String changeName) {
super(firstName);//显式调用父类带参数的构造方法
this.firstName = changeName;
}
}
public class Test {
public static void main(String[] args) {
Son s = new Son("张","李");
System.out.println(s.getFirstName());
}
}
运行结果:
李
2)调用父类的属性和成员方法
public class Father {
protected String firstName ;
Father(String firstName){
this.firstName = firstName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void fn(){
System.out.println("我是Father fn()...");
}
}
public class Son extends Father {
String firstName = "李";
@Override
public String getFirstName() {
return firstName;
}
@Override
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public Son(String firstName,String changeName) {
super(firstName);//显式调用父类带参数的构造方法
this.firstName = changeName;
}
@Override
public void fn() {
super.fn(); //调用父类的成员方法
System.out.println("Father fisrtName:"+super.firstName); //调用父类的属性
System.out.println("Son fisrtName:"+this.firstName);
}
}
public class Test {
public static void main(String[] args) {
Son s = new Son("张","李");
s.fn();
}
}
运行结果:
我是Father fn()...
Father fisrtName:张
Son fisrtName:李
1)子类的构造方法中必须调用父类的构造方法。
2)子类可以覆盖从父类继承过来的属性,覆盖后this.xxx获得的是覆盖后的属性,super.xxx覆盖之前父类的属性。
3)在Java中super有两种使用场景。1.调用父类的构造方法。2.调用父类的属性和方法。
4)通常情况下,在构造方法中this和super不能同时出现。(感兴趣的亲们,可以自己亲测!)