一、super关键字的使用1. 为什么需要super?举例1:子类继承父类以后,对父类的方法进行了重写,那么在子类中,是否还可以对父类中被重写的方法进行调用? 可以!举例2:子类继承父类以后,发现子类和父类中定义了同名的属性,是否可以在子类中区分两个同名的属性? 可以! 如何调用? 使用super关键字即可。2. super的理解:父类的3. super可以调用的结构:属性、方法、构造器具体的: 3.1 super调用属性、方法子类继承父类以后,我们就可以在子类的方法或构造器中,调用父类中声明的属性或方法。(满足封装性的前提下) 如何调用呢?需要使用"super."的结构,表示调用父类的属性或方法。 一般情况下,我们可以考虑省略"super."的结构。但是,如果出现子类重写了父类的方法或子父类中出现了同名的属性时, 则必须使用"super."的声明,显式的调用父类被重写的方法或父类中声明的同名的属性。举例1:子类继承父类以后,对父类的方法进行了重写,那么在子类中,是否还可以对父类中被重写的方法进行调用? 可以!
package chapter07_oop2.src.com.atguigu05._super;/*** ClassName: Person* Description:** @Author 尚硅谷-宋红康* @Create 9:08* @Version 1.0*/ public class Person {//属性String name;//方法public void eat(){System.out.println("人吃饭");}public void sleep(){System.out.println("人睡觉");}}
package chapter07_oop2.src.com.atguigu05._super;/*** ClassName: Student* Description:** @Author 尚硅谷-宋红康* @Create 9:08* @Version 1.0*/ public class Student extends Person {String school;public void study(){System.out.println("学生学习");}public void eat(){System.out.println("学生应该多吃有营养的食物");}public void sleep(){System.out.println("学生保证每天不低于10小时的睡眠");}public void show(){eat(); //省略了thisthis.eat();super.eat();}}
package chapter07_oop2.src.com.atguigu05._super;/*** ClassName: StudenTest* Package: chapter07_oop2.src.com.atguigu05._super* Description:** @Author 小白* @Create 2024/4/2 11:14* @Version 1.0*/ public class StudenTest {public static void main(String[] args) {Student s1 = new Student();s1.eat();s1.sleep();s1.show();}}
如果子类没有重写父类中的方法 如果父类还是没有找到 就会找到Object 如果Object还是没有找到 则报错
举例2:子类继承父类以后,发现子类和父类中定义了同名的属性,是否可以在子类中区分两个同名的属性? 可以!
现在是有五个属性
package chapter07_oop2.src.com.atguigu05._super;/*** ClassName: Person* Description:** @Author 尚硅谷-宋红康* @Create 9:08* @Version 1.0*/ public class Person {//属性String name;private int age;int id = 1001; //身份证号//方法public void eat(){System.out.println("人吃饭");}public void sleep(){System.out.println("人睡觉");}public void doSport(){System.out.println("人运动");}}
package chapter07_oop2.src.com.atguigu05._super;/*** ClassName: Student* Description:** @Author 尚硅谷-宋红康* @Create 9:08* @Version 1.0*/ public class Student extends Person {String school;int id = 1002; //学号public void study(){System.out.println("学生学习");}public void eat(){System.out.println("学生应该多吃有营养的食物");}public void sleep(){System.out.println("学生保证每天不低于10小时的睡眠");}public void show(){eat(); //省略了thisthis.eat();super.eat();}public void show1(){doSport();this.doSport();super.doSport();}public void show2(){System.out.println(id); //1002 找最近System.out.println(this.id);//1002 找最近System.out.println(super.id); //1001 找父类的属性}}
package chapter07_oop2.src.com.atguigu05._super;/*** ClassName: StudenTest* Package: chapter07_oop2.src.com.atguigu05._super* Description:** @Author 小白* @Create 2024/4/2 11:14* @Version 1.0*/ public class StudenTest {public static void main(String[] args) {Student s1 = new Student();s1.eat();s1.sleep();s1.show();s1.doSport();s1.show2();}}
总结:加不加super 区别在于有没有同名 如果没有同名 结果都是一样的
3.2 super调用构造器 ① 子类继承父类时,不会继承父类的构造器。只能通过“super(形参列表)”的方式调用父类指定的构造器。
举例:
package chapter07_oop2.src.com.atguigu05._super;/*** ClassName: Person* Description:** @Author 尚硅谷-宋红康* @Create 9:08* @Version 1.0*/ public class Person {//属性String name;private int age;int id = 1001; //身份证号public Person() {System.out.println("Person()....");}public Person(String name, int age) {this.name = name;this.age = age;}public Person(String name, int age, int id) {this.name = name;this.age = age;this.id = id;}//方法public void eat(){System.out.println("人吃饭");}public void sleep(){System.out.println("人睡觉");}public void doSport(){System.out.println("人运动");}}
package chapter07_oop2.src.com.atguigu05._super;/*** ClassName: Student* Description:** @Author 尚硅谷-宋红康* @Create 9:08* @Version 1.0*/ public class Student extends Person {String school;int id = 1002; //学号public void study(){System.out.println("学生学习");}public void eat(){System.out.println("学生应该多吃有营养的食物");}public void sleep(){System.out.println("学生保证每天不低于10小时的睡眠");}public void show(){eat(); //省略了thisthis.eat();super.eat();}public void show1(){doSport();this.doSport();super.doSport();}public void show2(){System.out.println(id); //1002 找最近System.out.println(this.id);//1002 找最近System.out.println(super.id); //1001 找父类的属性}//测试super调用父类的构造器public Student(){super();System.out.println("Student()...");}}
package chapter07_oop2.src.com.atguigu05._super;/*** ClassName: StudenTest* Package: chapter07_oop2.src.com.atguigu05._super* Description:** @Author 小白* @Create 2024/4/2 11:14* @Version 1.0*/ public class StudenTest {public static void main(String[] args) {Student s1 = new Student();s1.eat();s1.sleep();s1.show();s1.doSport();s1.show2();//************************System.out.println();Student s2 = new Student();}}
② 规定:“super(形参列表)”,必须声明在构造器的首行。
③ 我们前面讲过,在构造器的首行可以使用"this(形参列表)",调用本类中重载的构造器,结合②,结论:在构造器的首行,"this(形参列表)" 和 "super(形参列表)"只能二选一。
④ 如果在子类构造器的首行既没有显示调用"this(形参列表)",也没有显式调用"super(形参列表)",则子类此构造器默认调用"super()",即调用父类中空参的构造器。
⑤ 由③和④得到结论:子类的任何一个构造器中,要么会调用本类中重载的构造器,要么会调用父类的构造器。只能是这两种情况之一。
⑥ 由⑤得到:一个类中声明有n个构造器,最多有n-1个构造器中使用了"this(形参列表)",则剩下的那个一定使用"super(形参列表)"。
--> 我们在通过子类的构造器创建对象时,一定在调用子类构造器的过程中,直接或间接的调用到父类的构造器。 也正因为调用过父类的构造器,我们才会将父类中声明的属性或方法加载到内存中,供子类对象使用。