【转】Java-super()的用法

用法一:子类重写父类的方法

package test;

public class A {

	private String nameA="A";

	public void getName() {

		System.out.println("父类" + nameA);

	}
	
	public static void main(String[] args) {

		B b = new B();
		b.getName();

	}

}

class B extends A{

	private String nameB = "B";

	@Override
	public void getName() {

		System.out.println("子类" + nameB);
		super.getName();

	}

}

运行结果:
在这里插入图片描述
结果分析:
在子类B中,我们重写了父类的getName方法,如果在重写的getName方法中我们去调用了父类的相同方法,必须要通过super关键字显示的指明出来。
如果不明确出来,按照子类优先的原则,相当于还是再调用重写的getName()方法,此时就形成了死循环,执行后会报java.lang.StackOverflowError异常。如下图所示:
在这里插入图片描述
在这里插入图片描述

用法二:子类重写父类的变量

package test;

public class A {

	String nameA = "A";
	
	public static void main(String[] args) {

		B b = new B();
		b.getName();

	}

}

class B extends A{

	String nameA = "B";

	public void getName() {

		System.out.println("子类" + nameA);
		System.out.println("父类" + super.nameA);

	}

}

在这里插入图片描述
此时子类B中有一个和父类一样的字段(也可以说成父类字段被隐藏了),为了获得父类的这个字段我们就必须加上super,如果没有加,直接写成name = name;不会报错,只是会警告,表示此条语句没有任何意义,因为此时都是访问的子类B里面的那么字段。
我们通过super是不能访问父类private修饰的变量和方法的,因为这个只属于父类的内部成员,一个对象是不能访问它的private成员的。

用法三:在子类的构造方法中

编译器会自动在子类构造函数的第一句加上 super(); 来调用父类的无参构造器;此时可以省略不写。如果想写上的话必须在子类构造函数的第一句,可以通过super来调用父类其他重载的构造方法,只要相应的把参数传过去就好。
因此,super的作用主要在下面三种情况下:
1、调用父类被子类重写的方法;
2、调用父类被子类重定义的字段(被隐藏的成员变量);
3、调用父类的构造方法;
其他情况,由于子类自动继承了父类相应属性方法,关键字super可以不显示写出来。

关于构造方法中super()

第一种情况:编译不通过

package test;

public class A {

	public A (String s) {
		
	}
	
}

class B extends A{

	int a = 0;

}

在这里插入图片描述
分析:
如果一个类中没有写任何的构造方法,JVM会生成一个默认的无参构造方法。在继承关系中,由于在子类的构造方法中,第一条语句默认为调用父类的无参构造方法(即默认为super(),一般这句话省略了)。所以当在父类中定义了有参构造函数,都是没有定义无参构造函数时,IDE会强制要求我们定义一个相同参数类型的构造器。
在本例中JVM默认给B加了一个无参构造方法,而在这个方法中默认调用了super(),但是父类中并不存在该构造方法。

第二种情况:编译不通过

package test;

public class A {

	public A (String s) {
		
	}
	
}

class B extends A{

	public B(String s) {
		
	}

}

在这里插入图片描述
同样编译错误,相同的道理,虽然我们在子类中自己定义了一个构造方法,但是在这个构造方法中还是默认调用了super(),但是父类中并不存在该构造方法。

第三种情况:成功编译通过

package test;

public class A {
	
	public A(String s) {
		
	}
 
}
 
class B extends A{
	
	public B(String s) {
		
		super(s);
		
	}
	
}

分析:
所以,只要记住,在子类的构造方法中,只要里面没有显示的通过super去调用父类相应的构造方法,默认都是调用super(),即无参构造方法,因此要确保父类有相应的构造方法。

发布了53 篇原创文章 · 获赞 33 · 访问量 1278

猜你喜欢

转载自blog.csdn.net/qq_44458489/article/details/104826027