1. 概念
super()是一个关键字,用于调用父类的构造方法。每当子类要实例化时,子类的构造方法都会首先调用父类的构造方法(必须是子类构造方法的第一行,不然程序会报错),这个是默认的,不管我们有没有写 super() 关键字去调用,它都会有一个默认的 super() 关键字(没写会默认调用父类的无参构造方法),以确保父类的初始化能够完成。(除了object类以外)
注意:当父类没有提供无参构造方法时(即父类中存在有参构造方法,又没有显示地写出无参构造方法),子类中又没有显示地调用父类地有参构造方法,那么编译时就会报错。所以我们在设计类的时候,就要考虑到父类中至少要有一个构造方法能够被子类调用。
2.代码示例
(1)super()的使用
我们先以简单的动物类(Animal) 为例。
父类 动物类(Animal):
class Animal {
private final int age;
private final String name;
public int getAge() {
return age;
}
public String getName() {
return name;
}
public Animal(int age, String name) {
this.age = age;
this.name = name;
}
}
注意我们在父类Animal中有两个私有的属性 age 和 name ,这两个私有的属性是不能被子类继承和直接访问的,有三个公共的方法,getName()、getAge() 和 构造方法 Animal( int age, String name) 是可以被子类继承和访问的。
子类 小猫类(Cat):
class Cat extends Animal {
public Cat( int age, String name) {
super(age,name);
}
}
在子类中我们是没有定义属性的,只有一个公共的有参构造方法,在构造方法中,我们使用了super() 关键字来调用父类的构造方法 Animal( int age, String name) 来初始化父类的属性(在构造子类对象时,首先要构造父类的特征)。
主类 :
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int age = s.nextInt();
String name = s.next();
Animal cat = new Cat(age,name);
System.out.println("小猫的年龄:" + cat.getAge() + " ,小猫的名字:" + cat.getName());
}
}
虽然子类无法直接调用父类中的私有属性,但是我们可以通过父类中的公共方法去访问父类中的私有属性。
(2)在new一个子类对象时,要怎么去分配内存
class Animal {
private int age;
private String name;
}
在 Animal类 中我们只有两个私有属性,没有公共方法,只有一个默认的无参构造方法。
class Cat extends Animal {
public Cat() {
super();
}
}
在子类中我们有一个无参构造,在无参构造中,我们又调用了父类的无参构造方法,初始化了父类的特征,将 age 初始化为 0,name 初始化为 null。那么我们在 new 一个Cat类时,该怎么为它分配内存呢。
虽然父类中的私有属性,子类无法继承,但是在使用子类构造方法时,我们首先会调用父类无参构造方法,那么这个时候系统会分配两个内存条来存储 age 和 name。但是我们却无法用子类直接访问它们,而在父类中又没有能访问父类的私有属性的公共方法,所以虽然在内存中存储了 age 和 name 的实例值,但是我们却无法通过子类调用它们。