一、
public class Father {
private int a = 0;
public Father() {
System.out.println("Father:constructor");
}
public void set_a(int num) {
this.a = num;
System.out.println("Father:print a = " + a);
}
public static void main(String[] args) {
Father obj = new Father();
obj.set_a(2);
}
}
在这里,我们给Father类写了个构造方法。创建了一个对象,并调用其set_a()方法为a赋值并打印赋值后的结果。
运行结果:
Father:constructor
Father:print a = 2
小结:
1.这段代码里,如果我们没有写这个Father()构造方法的话,也会存在一个默认的构造方法。
2.obj对象调用了set_a()方法为a赋值,注意这里的this关键字,这个this的意思是本类的对象,即“自己”。我们可能会创建很多Father类的对象,哪个对象调用set_a()方法,被赋值的a就是哪个对象的。如果把this去掉,在这里运行结果是一样的。
二、
新建一个Son类继承Father类:
public class Son extends Father {
public static void main(String[] args) {
Son obj = new Son();
}
}
运行结果:
Father:constructor
小结:
Son子类并没有写构造方法,只有默认的构造方法。但是我们通过new创建Son的对象的时候,是会调用父类的构造方法的。但是调用父类和子类的构造方法顺序如何呢?
三、
将Son类改动如下:
public class Son extends Father {
public Son() {
System.out.println("Son:constructor");
}
public static void main(String[] args) {
Son obj = new Son();
}
}
运行结果:
Father:constructor
Son:constructor
小结:
可以看出new一个Son对象的时候,是会先调用父类的构造方法,再调用子类的构造方法。
四、
将父类改动如下:
public class Father {
private int a = 0;
public Father(int a) {//加上参数
System.out.println("Father:constructor");
}
public void set_a(int num) {
this.a = num;
System.out.println("Father:print a = " + a);
}
public static void main(String[] args) {
Father obj = new Father(5);
obj.set_a(2);
}
}
子类不变。
结果:
Father类可以正常运行,输出:
Father:constructor
Father:print a = 2
Son类会报错不能编译运行。
小结:
Son类报错的原因是因为创建Son对象时,需要调用父类的构造方法。但是父类的构造方法是有参数的。而我们在创建Son对象的时候并没有传入参数。
但是注意,如果我们把Son的main方法里对象的创建就这么加上参数,如Son obj = new Son(3);也是会报错不能编译运行的。
这个问题怎么解决呢?
五、
可以用super关键字来解决。
子类改为:
public class Son extends Father {
public Son() {
super(4);//加上super,并传入参数
System.out.println("Son:constructor");
}
public static void main(String[] args) {
Son obj = new Son();
}
}
运行结果:
Father:constructor
Son:constructor
小结:
super()的意思是调用父类的构造方法。在这个例子里,我们在子类的构造方法里,用super()调用了父类的构造方法。因此解决了必须调用父类构造方法而又得带参数的问题。
六、
再将子类改动如下:
public class Son extends Father {
public Son() {
super(4);
super.set_a(5);//super调用父类方法
System.out.println("Son:constructor");
}
public static void main(String[] args) {
Son obj = new Son();
}
}
运行结果:
Father:constructor
Father:print a = 5
Son:constructor
小结:
super.set_a(5)运行时,会调用Father类的set_a()方法:
public void set_a(int num) {
this.a = num;
System.out.println("Father:print a = " + a);
}
这里,this.a被赋值为5, 但是哪个a被赋值为5了呢?
因为调用set_a()方法的是super,也就是Father类。因此这里的this指的就是默认构造的Father对象。也就是这个Father对象的a被赋值为5了。
注意:this和super不能用在static静态方法中。假如我们在main方法里写一句this.set_a(5);或者super.set_a(5);是会报错的。因为static方法是不依赖于具体对象的,而this和super是依赖具体对象的。