一、什么是super?
它是一个指代变量,是直接父类对象的引用,用于在子类中指代父类对象。
二、应用
2.1 应用范围
只能用于子类的构造函数和实例方法中,不能用于子类的类(静态)方法中。
原因:super指代的是一个父类的对象,是需要在运行时被创建的,而静态方法是类方法,它是类的一部分。在类被载入时,方法已经存在,但是父类对象还没被创建。
2.2 如何使用
2.2.1 通过super关键字在子类中调用父类的成员变量或方法
可用下列方式调用:
super.<成员变量名>
super.<成员方法名>
/**
* 测试super用法一
* @author Java_biao
*
*/
public class TestSuper01 {
public static void main(String[] args) {
ChildClass01 child = new ChildClass01();
child.printValue();
child.showInfo();
}
}
class FatherClass01 {
int value = 100;
public void info() {
System.out.println("this is FatherClass...");
}
}
class ChildClass01 extends FatherClass01 {
/* 子类除了继承父类所具有的valu属性外,自己又另外声明了一个value属性,
* 也就是说,此时的子类拥有两个value属性。 */
int value = 200;
@Override
public void info() {
System.out.println("this is ChildClass...");
}
public void printValue() {
/*调用父类value值*/
System.out.println("The value of FatherClass: "+super.value);
/*调用子类value值*/
System.out.println("The value of ChildClass: "+this.value);
}
public void showInfo() {
super.info(); //调用父类中被重写的方法
this.info(); //调用子类方法
}
}
测试结果:
2.2.2 通过super关键字调用父类中定义的构造方法
可用下列方式调用:
super() //调用无参构造器
super(参数1[, 参数2, ...参数n]) //调用有参构造器
其中调用参数列表必须和父类的某个构造函数方法的参数列表完全匹配。
子类与其直接父类之间的构造方法存在约束关系,有以下几条重要原则:
(1)按继承关系,构造方法是从顶向下进行调用的。
(2)如果子类没有构造方法,则它默认调用父类无参的构造方法,如果父类中没有无参数的构造方法,则将产生错误。
(3)如果子类有构造方法,那么创建子类的对象时,先执行父类的构造方法,再执行子类的构造方法。
(4)如果子类有构造方法,但子类的构造方法中没有super关键字,则系统默认执行该构造方法时会产生super()代码,即该构造方法会调用父类无参数的构造方法。
(5)对于父类中包含有参数的构造方法,子类可以通过在自己的构造方法中使用super关键字来引用,而且必须是子类构造函数方法中的第一条语句。
(6)Java语言中规定当一个类中含有一个或多个有参构造方法,系统不提供默认的构造方法(即不含参数的构造方法),所以当父类中定义了多个有参数构造方法时,应考虑写一个无参数的构造方法,以防子类省略super关键字时出现错误。
(7) 子类的静态方法中不能使用super关键字。
/**
* 测试super用法二
* @author Java_biao
*
*/
public class TestSuper02 {
public static void main(String[] args) {
/**
* 当实例化对象时,会先调用父类的构造器,在调用子类构造器
*/
ChildClass02 child = new ChildClass02();
}
}
class FatherClass02 {
int value;
public FatherClass02() {
System.out.println("这是父类无参构造器");
}
}
class ChildClass02 extends FatherClass02 {
int id;
public ChildClass02() {
/*此处实际上系统默认执行super()*/
System.out.println("这是子类无参构造器");
}
}
测试结果:
/**
* 测试super用法二
* @author Java_biao
*
*/
class FatherClass03 {
int id;
String name;
int value;
public FatherClass03() {
System.out.println("这是父类无参构造器");
}
public FatherClass03(String name) {
this.name = name;
System.out.println("这是父类有参构造器1");
}
public FatherClass03(String name, int value) {
this.name = name;
this.value = value;
System.out.println("这是父类有参构造器2");
}
}
class ChildClass03 extends FatherClass03 {
public ChildClass03() {
System.out.println("这是子类无参构造器");
}
public ChildClass03(String name) {
super(name);
System.out.println("这是子类有参构造器1");
}
public ChildClass03(String name, int value) {
super(name, value);
System.out.println("这是子类有参构造器2");
}
}
public class TestSuper03 {
public static void main(String[] args) {
/* 先调用父类有参构造器1,再调用子类有参构造器1*/
ChildClass03 child1 = new ChildClass03("Java_biao");
/* 先调用父类有参构造器2,再调用子类有参构造器2*/
ChildClass03 child2 = new ChildClass03("Java_biao", 200);
}
}
测试结果:
三、总结
1、通过super关键字在子类中调用父类的成员变量或方法
2、通过super关键字调用父类中定义的构造方法
参考博客:https://blog.csdn.net/zai_xia/article/details/79946984