super关键字详解
由于子类不能继承父类的构造方法,因此,如果要调用父类的构造方法,可以使用super关键字。
super可以用来访问父类的构造方法,普通方法和属性。
super关键字的功能:
- 在子类的构造方法中显式的调用父类构造方法
- 访问父类的成员方法和变量。
super调用父类构造方法
super关键字可以在子类中的构造方法中显示地调用父类的构造方法,基本格式如下:
super(argument-list);
其中,argument-list指父类构造方法中的参数列表。super()必须是在子类构造方法的方法体中的第一行。
示例:声明父类Person和子类Student,在Person类中定义一个带有参数 的构造方法,代码如下:
public class Person {
public Person(String name) {
}
}
public class Student extends Person {
}
会发现Student类出现编译错误,提示必须显示定义构造方法,错误信息如下:
Implicit super constructor Person() is undefined for default constructor. Must define an explicit constructor
之所以会报错,是因为本例中JVM默认给Student类加了一个无参构造方法,而在这个方法中默认调用了super(),但是Person类中并不存在该构造方法,所以会编译错误。
如果一个类中没有写任何的构造方法,JVM会生成一个磨人的无参构造方法。在继承关系中,由于在子类的构造方法中,第一条语句默认为调用父类的无参构造方法(即默认为super(),一般这行代码省略不写)。所以当在父类中定义了有参构造方法,但是没有定义无参构造方法时,编译器会强制要求我们定义一个相同参数类型的构造方法。
示例: 声明父类 Person,类中定义两个构造方法。示例代码如下:
public class Person {
public Person(String name, int age) {
}
public Person(String name, int age, String sex) {
}
}
子类Student继承了Person类,使用super语句来了定义Student类的构造方法。示例代码如下:
public class Student extends Person {
public Student(String name, int age, String birth) {
super(name, age); // 调用父类中含有2个参数的构造方法
}
public Student(String name, int age, String sex, String birth) {
super(name, age, sex); // 调用父类中含有3个参数的构造方法
}
}
从上述Student类构造方法代码可以看出,super可以用来直接调用父类中的构造方法,使编写代码也更加简洁方便。
编译器会自动在子类构造方法的第一句加上super();来 调用父类的无参构造方法, 必须写在子类构造方法的第一句,也可以省略不写。通过 super 来调用父类其它构造方法时,只需要把相应的参数传过去。
super访问父类成员
当子类的成员变量或方法与父类同名时,可以使用 super 关键字来访问。如果子类重写了父类的某一个方法,即子类和父类有相同的方法定义,但是有不同的方法体,此时,我们可以通过 super 来调用父类里面的这个方法。
使用 super 访问父类中的成员与 this 关键字的使用相似,只不过它引用的是子类的父类,语法格式如下:
super.member
其中,member 是父类中的属性或方法。使用 super 访问父类的属性和方法时不用位于第一行。
super调用成员属性
当父类和子类具有相同的数据成员时,JVM 可能会模糊不清。我们可以使用以下代码片段更清楚地理解它。
class Person {
int age = 12;
}
class Student extends Person {
int age = 18;
void display() {
System.out.println("学生年龄:" + super.age);
}
}
class Test {
public static void main(String[] args) {
Student stu = new Student();
stu.display();
}
}
运行结果为:
学生年龄:12
在上面的例子中,父类和子类都有一个成员变量 age。我们可以使用 super 关键字访问 Person 类中的 age 变量。
super调用成员方法
当父类和子类都具有相同的方法名时,可以使用 super 关键字访问父类的方法。具体如下代码所示。
class Person {
void message() {
System.out.println("This is person class");
}
}
class Student extends Person {
void message() {
System.out.println("This is student class");
}
void display() {
message();
super.message();
}
}
class Test {
public static void main(String args[]) {
Student s = new Student();
s.display();
}
}
运行结果为:
This is student class
This is person class
在上面的例子中,可以看到如果只调用方法 message( ),是当前的类 message( ) 被调用,使用 super 关键字时,是父类的 message( ) 被调用。