super关键字
为什么需要super:
举例1: 子类继承父类以后,对父类的方法进行重写,那么在子类中,使用super关键字仍然可以对父类中重写的方法进行调用
举例2: 子类继承父类以后,发现子类和父类中定义了同名的属性,使用super关键字仍然可以在子类中区分这两个同名的属性
super的理解: 父类的
super可以调用的结果:属性、方法、构造器
super调用属性、方法
子类继承父类以后,我们就可以在子类的方法或构造器中,调用父类中声明的属性或方法。(满足封装性前提下)
调用时,需要使用 "super." 的结构,表示调用父类的属性或方法,一般情况下可以省略。
但是! 如果出现了子类重写了父类的方法或同名的属性时,则必须使用 "super." 结构,显示的调用父类中被重写的方法或属性。
public class Person { //属性 String name; private int age; int id = 1001; public void eat(){ System.out.println("人会吃饭!"); } public void sleep(){ System.out.println("人会睡觉!"); } }
public class Student extends Person{ String school; int id = 1002; public void eat(){ //重写 System.out.println("学生要多吃有营养的食物!"); } public void show(){ super.eat(); //调用父类中的eat方法 } public void show2(){ System.out.println(id); // 子类的id System.out.println(this.id); // 子类的id System.out.println(super.id); // 父类的id } }
public class StudentTest { public static void main(String[] args) { Student s = new Student(); s.eat(); //学生要多吃有营养的食物! s.show(); //人会吃饭! s.show2(); } }
super调用构造器
- 子类继承父类时,不会继承父类的构造器。只能通过 "super(形参列表)" 的方式调用父类指定的构造器
- 规定: "super(形参列表)" ,必须声明在子类构造器的首行
- 前面提到,在构造器的首行可以使用 "this(形参列表)" ,调用本类中重载的构造器, 结合上一点,在构造器的首行this和super只能二选一
- 如果在子类构造器的首行既没有显示调用 "super(形参列表)" ,也没调用 "this(形参列表)" 。则子类此构造器默认调用 "super( )"即父类的空参构造器
- 子类的任何一个构造器,要么调用本类中重载的构造器,要么调用父类的构造器,只能二选一。
- 一个类中声明有n个构造器,最多有n-1个构造器使用 "this(形参列表)",则剩下的那一个构造器一定使用 "super(形参列表)"
注意: 我们在通过子类的构造器创建对象时,一定在调用子类构造器的过程中,直接或间接的调用到父类的构造器。也正因为调用过父类的构造器,我们才会将父类中声明的属性或方法加载到内存中,供子类对象使用。
public class Person { //属性 String name; private int age; int id = 1001; public Person(){ System.out.println("Person()...."); } public Person(String name, int age, int id) { this.name = name; this.age = age; this.id = id; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public void eat(){ System.out.println("人会吃饭!"); } public void sleep(){ System.out.println("人会睡觉!"); } }
public class Student extends Person{ String school; int id = 1002; public Student(){ super(); //super必须在构造器的首行! System.out.println("Student()...."); } public Student(String name,int age){ this.name = name; setAge(age); //这里age是private 所以只能通过方法赋值 } public void eat(){ //重写 System.out.println("学生要多吃有营养的食物!"); } public void show(){ super.eat(); //调用父类中的eat方法 } public void show2(){ System.out.println(id); // 子类的id System.out.println(this.id); // 子类的id System.out.println(super.id); // 父类的id } }
public class StudentTest { public static void main(String[] args) { Student s = new Student(); //输出:Person().... Student().... // Student s2 = new Student("小红",21); //输出:Person().... } }
子类对象实例化全过程
从结果的角度看:体现为类的继承性
当创建子类对象后,子类对象就获取了其父类中声明的所有的属性和方法,在权限允许的情况下,可以直接调用
从过程的角度来看:
当我们通过子类的构造器创建对象时,子类的构造器一定会直接或间接的调用到其父类的构造器,而其父类的构造器同样会调用其父类的父类的构造器....直到调用了object类中的构造器为止。
正因为调用过子类的所有父类的构造器,所以我们会将父类中声明的属性、方法加载到内存中,供子类的对象使用
标签:调用,Java,子类,基础,id,父类,super,public From: https://www.cnblogs.com/gjwqz/p/18370385