Java教程
Java标识符与关键字
Java变量
Java数据类型
Java运算符
Java控制语句
Java方法
Java面向对象
Java对象的创建和使用
Java封装
Java中static和this
Java继承
Java方法覆盖和多态
Java super
Java基础练习题

Java中super关键字的使用(在实例方法中)

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();
	}
}
运行结果如下图所示:

Java应用

图14-11:super和this

我们发现printName()方法中的super.name和this.name最终输出结果是一样的,这是为什么呢?请看以上程序执行的内存图:

Java编程

图14-12:父类的构造方法执行结束之后的内存图

Java开发

图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呢,我们一起来看看以上程序的内存图:

Java技术架构

图14-15:父类Book的构造方法执行之后的内存图

Java应用

图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();
	}
}
运行结果如下图所示:

Java技术架构

图14-17:运行结果

通过以上测试得出最终结论:父类和子类中有同名实例变量或者有同名的实例方法,想在子类中访问父类中的实例变量或实例方法,则super是不能省略的,其它情况都可以省略。 

全部教程