首先创建两个类Person和Student,Student继承自Person,里面随便定义一些属性和方法
package com.wen4; public class Person { int age; public void eat(){ System.out.println("eat"); } }
package com.wen4; public class Student extends Person{ double score; public void study(){ System.out.println("learn"); } public void practice(){ System.out.println(age); eat(); } }
因为Student继承自Person,所以Student里面practice方法里面的age指的是父类Person中的age,eat方法指的是父类Person中的方法,但是我们如何显示的表达出来,可以在前面加上"super."
public void practice(){ System.out.println(super.age); super.eat(); }
所以由案例可以总结
- super指的是:父类的
- super可以修饰属,方法
在子类方法中,可以通过super.属性 super.方法的方式,显示调用父类提供的属性方法,通常情况下可不写
但是在特殊情况下super.不能省略
package com.wen4; public class Student extends Person{ int age = 20; double score; public void study(){ System.out.println("learn"); } public void eat(){ System.out.println("student类中的eat方法"); } public void practice(){ System.out.println(super.age); super.eat(); } }
此时子类Student中也有age属性和eat方法的重写,如果不加super关键字,那么程序会遵循就近原则,优先使用子类Student中的age属性和eat方法,此时相当于省略this关键字,如下:
public void practice(){ System.out.println(this.age); this.eat(); }
所以由此案例可以总结:
- 当子类中属性与父类中属性重名时,如果要想要使用父类中的属性,不能省略super.
- 子类中存在方法重写,使用父类中的方法就不能省略super.
依旧举例说明
package com.wen5; public class Person { int age; String name; public Person(){ } }
package com.wen5; public class Student extends Person { double score; public Student(){ } }
package com.wen5; public class Test { public static void main(String[] args) { Student xiaoWen = new Student(); } }
这里创建一个xiaoWen对象,首先程序执行到这一步,先进行类的加载(这个不懂可以跳过,不影响),然后进入到Student类的构造器中,然后进入Person类的构造器中,所以实际上,当创建一个对象时,程序会一层一层向上调用构造器进行类的初始化 *** 作,就如例子:Studnet ==> Person ⇒ Object.
程序中就相当于省略了super(); 一般情况下省略不写
package com.wen5; public class Student extends Person { double score; public Student(){ super(); } }
下面我们使用super()调用父类构造器进行属性初始化,更深入理解super的妙用
package com.wen5; public class Person { int age; String name; public Person(){ } public Person(int age, String name){ this.age = age; this.name = name; } }
package com.wen5; public class Student extends Person { double score; public Student(int age, String name, double score){ super(age, name); // 调用父类的构造器 this.score = score; } }
在构造器中,super调用父类构造器和this调用子类构造器只能存在一个,二者不能共存.
表层原因:
super修饰构造器只能放在第一行,this修饰构造器也要放在第一行
深层原因:
假如可以存在(错误案例,便于理解,实际不能运行)
package com.wen5; public class Student extends Person { double score; public Student(double score){ super();//程序默认分配了,不写,这里显示的写出来,方便理解 this.score = score; } public Student(int age, String name, double score){ super(age, name); this(score); } }
super(age, name)对父类Person进行了一次初始化,当执行到this(score),再一次执行super(),相当于再一次初始化Person,冲突了也就是所谓的不合理,所以在构造器中,表示调用构造器时候,this和super不能同时存在
注意:
总结:一般情况下,所有的构造器第一行默认情况下都有super(),但是一旦显示的使用了super()调用了父类构造器或者使用this()调用了子类构造器,那么这个 super()就不会给你默认分配了
super关键字:引用父类的,找父类的xx
用法:
(1)super.属性
当子类声明了和父类同名的成员变量时,那么如果要表示某个成员变量是父类的,那么可以加“super.”
(2)super.方法
当子类重写了父类的方法,又需要在子类中调用父类被重写的方法,可以使用"super."
(3)super()或super(实参列表)
super():表示调用父类的无参构造
super(实参列表):表示调用父类的有参构造
注意:
(1)如果要写super()或super(实参列表),必须写在子类构造器的首行
(2)如果子类的构造器中没有写:super()或super(实参列表),那么默认会有 super()
(3)如果父类没有无参构造,那么在子类的构造器的首行“必须”写super(实参列表)
(4)构造器中super调用父类构造器和this调用子类构造器不能共存
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)