一,什么是super关键字及其作用
super主要是在继承关系下 存在于子类方法中,用于指向子类对象中父类对象。
二,super关键字的三种用法及其在构造方法中的注意事项
1:super.父类的成员变量
(1)如下代码所示,当想访问父类里面的成员变量b,调用show()方法,子类中没有该成员变量b时,会自行向上查找(即继承关系下的父类)。显示的写super时.它一定指向父类的成员变量,所以在成员变量不同名的情况下,super可以省略。
public class Test1 {
public static void main(String[] args) {
Zi zi = new Zi();
zi.show();
}
}
class Fu {
public int a = 10;
public int b=20;
}
class Zi extends Fu{
public int a = 20;
public int c;
public void show() {
//访问父类里面的非private修饰的成员变量(不同名)
System.out.println(b);
System.out.println(super.b);
}
}
(2)想访问子父类同名的成员变量a时,调用show()方法,当没有显示的写super或者写this(this指向最终调用他的对象)关键字时,访问的是子类的的成员变量a,当显示的写super时.它一定访问的是父类的的成员变量a。
public class W1 {
public static void main(String[] args) {
Zi zi = new Zi();
zi.show();
}
}
class Fu {
public int a = 10;
public int b=20;
}
class Zi extends Fu{
public int a = 20;
public int c;
public Zi() {
super();
}
public void show() {
//访问子类和父类中同名的成员变量
System.out.println(a);//访问子类
System.out.println(this.a);//访问子类
System.out.println(super.a);//访问父类
}
运行结果如图所示:
2:super.父类的成员方法
。 当想访问父类里面的成员方法fu(),调用show()方法,子类中没有该成员方法fu()时,会自行向上查找。显示的写super时.它一定指向父类的成员方法fu(),所以在成员方法不同名的情况下,super可以省略
public class W1 {
public static void main(String[] args) {
Zi zi = new Zi();
zi.test();
}
}
class Fu {
public void fu() {
System.out.println("父类");
}
}
class Zi extends Fu{
public void zi() {
System.out.println("子类");
}
public void test() {
//访问父类的 方法
fu();
this.fu();
super.fu();
}
}
(2)想访问子父类同名的成员方法时,调用show()方法,当没有显示的写super或者写this(this指向最终调用他的对象)关键字时,访问的是子类的的方法fu(),当显示的写super时.它一定访问的是父类的的成员方法fu()。
public class W1 {
public static void main(String[] args) {
Zi zi = new Zi();
zi.test();
}
}
class Fu {
public void method() {
System.out.println("父类method");
}
}
class Zi extends Fu{
public void method() {
System.out.println("子类method");
}
public void test() {
method();//调用子类method方法
this.method();//调用子类method方法
super.method();//调用父类的method方法
}
}
运行结果如下
3:super(参数)
在继承关系下要访问构造方法要注意以下几点:
(1):在子类构造方法中没有显示的写super(参数),则会默认赠送一个super();如果显示的写了super()则不再赠送,当然父类里面也可以写super(),是因为一个类没有显示的继承一个父类则默认继承Object顶级父类。
当我们用匿名对象 new Zi()创建子类对象(调用子类构造方法)时;无论如何都会调用父类的构造方法,①显示的写super()调用的是父类中的无参数的构造方法。
public class Test01 {
public static void main(String[] args) {
new Zi();
}
}
class Fu {
public Fu() {
super();
System.out.println("父类");
}
}
class Zi extends Fu{
public Zi() {
super();
System.out.println("子类");
}
}
运行结果
②显示的写super(参数)调用的是父类中的有参的构造方法。
public class Test01 {
public static void main(String[] args) {
new Zi();
}
}
class Fu {
public Fu(int a) {
System.out.println("父类有参构造");
}
}
class Zi extends Fu{
public Zi() {
super(100);
System.out.println("子类");
}
}
运行结果
(2):如果要显示的写,则super(参数)必须是第一个语句,且必须写在第一行,不能喝this()同时存在;
三,方法覆盖重写下super的用法
1.首先方法的覆盖重写是: a.在继承关系下,b.方法名相同、参数项相同 c.修饰符相同,参数项相同。
2.当有多个子类继承父类,有同一个行为方法或者成员信息的,又有又有自己独有的行为或者成员信息,即可子类可以覆盖重写父类的方法,又避免写大量的重复代码。
比如经理(Manager)和员工(Coder)都有work()方法,但又有自己独有的行为或者成员信息,就可以覆盖重写父类员工(Employee)的work()方法;work()方法里面可以写自己独有的行为,通过super();来调用父类的work()方法。
public class Test01 {
public static void main(String[] args) {
//通过无参数的构造方法,创建对象
Manager m = new Manager();
m.work();
}
}
class Employee {
public void work() {
System.out.print("在哪都痛公司,");
}
}
class Manager extends Employee{
//成员方法
public void work() {
//显示的说明调用父类的work方法
super.work();
System.out.print("经理正在努力的做着管理工作,分配任务,检查员工提交上来的代码.....");
}
}
class Coder extends Employee{
//成员方法
public void work() {
//显示的说明调用的是父类中的方法
super.work();
System.out.println("程序员正在努力的写着代码......");
}
}
运行结果如下