super和this都可以使用在实例方法中,并且都不能使用在静态方法当中,“this”大部分情况下都是可以省略的,只有在方法中区分局部变量和实例变量的时候不能省略。那“super”什么时候可以省略,什么时候不能省略呢?
//书
public class Book {
//书名
String name;
//构造方法
public Book(){
super();
}
public Book(String name){
super();
this.name = name;
}
}
//纸质书
public class PaperBook extends Book {
//构造方法
public PaperBook(){
super();
}
public PaperBook(String name){
super();
this.name = name;
}
//打印书名
public void printName(){
System.out.println("this.name->书名 : " + this.name);
System.out.println("super.name->书名 : " + super.name);
}
}
public class BookTest {
public static void main(String[] args) {
PaperBook book1 = new PaperBook("零基础学Java卷I");
book1.printName();
}
}
运行结果如下图所示:
图14-11:super和this
我们发现printName()方法中的super.name和this.name最终输出结果是一样的,这是为什么呢?请看以上程序执行的内存图:
图14-12:父类的构造方法执行结束之后的内存图
图14-13:子类的构造方法执行结束之后的内存图
通过以上内存结构图发现this.name和super.name实际上是同一块内存空间,所以它们的输出结果是完全一样的。接下来,我们再把以上的PaperBook类修改一下:
//纸质书
public class PaperBook extends Book {
String name; //在子类中也定义了一个name属性
//构造方法
public PaperBook(){
super();
}
public PaperBook(String name){
super();
this.name = name;//这里的this.name代表子类的name
}
//打印书名
public void printName(){
System.out.println("this.name->书名 : " + this.name);
System.out.println("super.name->书名 : " + super.name);
}
}
运行结果如下图所示:
图14-14:super和this的区别
为什么super.name是null呢,我们一起来看看以上程序的内存图:
图14-15:父类Book的构造方法执行之后的内存图
图14-16:子类PaperBook的构造方法执行结束之后的内存图
通过以上内存图可以清楚的看到,父类Book的构造方法在执行的时候给super.name赋值null,子类PaperBook的构造方法在执行的时候给this.name赋值“零基础学Java卷I”,由于在子类PaperBook中定义了重名的变量name导致在当前对象中有两个name,一个是从父类中继承过来的,一个是自己的,如果此时想访问父类中继承过来的name则必须使用super.name,当直接访问name或者this.name都表示访问当前对象自己的name。
通过以上的学习,大家知道super在什么情况下不能省略了吗?当父类中有该实例变量,子类中又重新定义了同名的实例变量,如果想在子类中访问父类的实例变量,super不能省略。实例方法是这样吗?我们可以来测试一下,请看代码:
public class Vip {
//Vip默认继承Object
//重写从Object类中继承过来的toString()方法
public String toString(){
return "我是金牌会员";
}
public void test(){
System.out.println(super.toString());
System.out.println(this.toString());
System.out.println(toString());
}
}
public class VipTest {
public static void main(String[] args) {
Vip vip = new Vip();
vip.test();
}
}
运行结果如下图所示:
图14-17:运行结果
通过以上测试得出最终结论:父类和子类中有同名实例变量或者有同名的实例方法,想在子类中访问父类中的实例变量或实例方法,则super是不能省略的,其它情况都可以省略。