1.super 关键字可以理解为父类的
2.可以用来调用的结构
3.super调用属性、方法
3.1我们可以在子类的方法或构造器中。通过使用"super.属性"或"super.方法"的方式,显式的调用父类中声明的属性或方法。但是,通常情况下,我们习惯省略"super(跟this差不多)"
eg:
父类:
public class Person {
public int id = 1001;
public void eat(){
System.out.println("人:吃饭");
}
}
子类:
public class Student extends Person{
public void eat() {
System.out.println("学生:多吃有营养的食物");
}
public void show(){
System.out.println("id = " + this.id);//1001
System.out.println("id = " + super.id);//1001(super一定代表是父类,如果父类中,没有id这个属性或者这个属性为私有的,则这句会报错)
}
}
3.2 特殊情况:当子类和父类中定义了同名的属性时,我们要想在子类中调用父类中声明的属性,则必须显式的 使用"super.属性"的式,表明调用的是父类中声明的属性。
eg:
父类:
public class Person {
public int id = 1001;
public void eat(){
System.out.println("人:吃饭");
}
}
子类:
public class Student extends Person{
private int id = 1002;
public void eat() {
System.out.println("学生:多吃有营养的食物");
}
public void show(){
System.out.println("id = " + this.id);//1002
System.out.println("id = " + super.id);//1001
}
}
3.3 特殊情况:当子类重写了父类中的方法以后,我们想在子类的方法中调用父类中被重写的方法时,则必须显式的使用"super.方法"的方式,表明调用的是父类中被重写的方法。
public void study(){
System.out.println("学生:学习知识");
this.eat();//学生:多吃有营养的食物
super.eat();//人:吃饭"
walk();
}
4.super调用构造器
- 我们可以在子类的构造器中显式的使用"super(形参列表)"的方式,调用父类中声明的指定的构造器
- "super(形参列表)"的使用,必须声明在子类构造器的首行!
- 我们在类的构造器中,针对于"this(形参列表)"或"super(形参列表)"只能二选一,不能同时出现
- 在构造器的首行,没有显式的声明"this(形参列表)“或"super(形参列表)”,则默认调用的是父类中空参的构造器:super()
- 在类的多个构造器中,至少有一个类的构造器中使用了"super(形参列表)",调用父类中的构造器
5.this和super的区别
1)为什么super(…)和this(…)调用语句不能同时在一个构造器中出现?**
因为在构造的时候只需要调用父类的super()作为初始化父类一次,如果super(…)和this(…)同时出现的话,那么就会出现初始化父类两次的不安全操作,因为当super(…)和this(…)同时出现的时候,在调用完了super(…)之后还会执行this(…),而this(…)中又会自动调用super(),这就造成了调用两次super()的结果(这是假设super(…)和this(…)同时出现时候,super(…)在this(…)前面,反过来出现也一样)
2)为什么super(…)和this(…)调用语句只能作为构造器中的第一句出现?
子类是从父类继承而来,继承了父类的属性和方法,如果在子类中先不完成父类的成员的初始化,则子类无法使用,因为在java中不允许调用没初始化的成员。在构造器中是顺序执行的,也就是说必须在第一行进行父类的初始化。而super能直接完成这个功能。This()通过调用本类中的其他构造器也能完成这个功能。 因此,this()或者super()必须放在第一行