super关键字用途:
• 使用super关键字访问父类成员
• 用super.成员变量名来引用父类成员变量
• 用super.方法名(参数列表),表示访问父类的方法。
• 用super构造方法(参数列表),表示访问父类构造方法
注意:
1.super只能出现在构造方法的第一行,通过当前的构造方法去 调用“父类”中对应的构造方法,目的是:创建子类对象时,先初始化父类型特征(通俗的说也就是,要想有儿子,得先有父亲)。
2.super能出现在实例方法和构造方法中,不能出现在静态方法中。
3.super大部分情况下是可以省略的。
那么在什么情况下是不能省略的呢?
当在子类对象中,子类想访问父类的东西,可以使用“super.”的方式访问。例如:方法覆盖后,子类内部虽然重写了父类的方法,但子类也想使用一下父类的被覆盖的方法,此时可以使用“super.”的方式。当子类中出现和父类一样的属性或者方法,此时,你要想去调用父类的那个属性或者方法,此时“super.”不能省略(也就是说“super.”是一个实例对象为了区分是子类的成员还是父类的成员。父类有,子类也有,子类想访问父类的,“super.”不能省略。)。
误区: 不要把super误认为是父类对象,在创建子类对象时,不会创建父类对象,只会将父类中的信息加载到子类对象中存储.
写两个类,Teacher和Person,Teacher继承Person。
//父类Person类
class Person{
//无参构造函数
public Person() {
System.out.println("Person类的无参数构造函数执行");
}
}
//子类Teacher类
class Teacher extends Person{
//无参构造函数
public Teacher() {
System.out.println("Teacher类的无参数构造函数执行");
}
}
执行以下代码:
Teacher d1 = new Teacher();
运行结果为:
Person类的无参数构造函数执行
Teacher类的无参数构造函数执行
我们发现实例化一个子类的对象,也就是调用了子类的构造方法,为什么父类的无参数构造方法也执行了,并在子类构造方法执行之前就已经执行了父类的无参数构造方法。
上面说了,super()只能在构造方法的第一行出现。我们猜想,难道子类的构造方法第一行有一个隐形的super()方法?答案是肯定的。
我们给子类的构造方法的第一行加上super():
//子类Teacher类
class Tercher extends Person{
//无参构造函数
public Teacher() {
super();
System.out.println("Teacher类的无参数构造函数执行");
}
}
再执行下面代码:
Teacher d1 = new Teacher();
运行结果为:
Animal类的无参数构造函数执行
Cat类的无参数构造函数执行
和刚才子类构造方法没加super()是一样的,所以说当子类的构造方法内第一行没有出现“super()”时,系统会默认给它加上无参数的"super()"方法。
上面说的都是无参数的“super”方法,我们也可以在构造方法的第一行使用有参数的“super(父类构造函数的参数列表)”,但要注意的是,当子类构造方法执行有参数的“super(参数列表)”方法,你得确保父类中也有对应的有参数构造方法,不然会编译报错。同样,当子类构造方法的第一行执行super()无参数方法,那么父类中一定要有无参数构造方法,有的人可能会在父类中写了有参数的构造方法,却忽略了写无参数构造方法,那么在子类构造方法内就会报错,因为当你在一个类中写了有参数的构造方法时,无参数构造方法就会不存在,你需要自己补上无参数的构造方法,这是一个良好的编程习惯。
无论你子类构造方法有没有“super()”方法,实例化子类对象一定一定会执行对应的父类构造方法,即不管实例化了一个怎样的孩子,它一定会先实例化一个对应的父亲。
注意:不管你创建什么对象,Object对象的无参数构造方法一定会先执行,因为Object是所有类的基类。