java基础篇(七)super关键字

时间:2023-02-15 18:46:55

super是java提供的一个关键字,用于子类中调用父类的构造函数,实例变量和方法。

1、 实例方法
如果需要在子类中调用父类被覆盖的实例方法,可以使用super来调用。
比如如下例子中,Ostrich类继承Bird类,并且覆盖了Bired类的fly()方法,要想继续调用父类的fly()方法,就在子类中添加一个callOverrideMethod()方法通过super显示调用父类被覆盖的实例方法,这样子类Ostrich既可以调用自身fly()方法,也可以调用父类Bird中被覆盖的fly方法。

public class Bird
{

public void fly()
{
System.out.println(“我会飞”);
}
}
public class Ostrich extends Bird
{

//重写Birds类的fly()方法
public void fly()
{
System.out.println(“我只能跑,不会飞”);
}
Public void callOverrideMethod()
{
//在子类中通过super显示调用父类被覆盖的实例方法
super.fly();//我会飞
}
}

注意,和this一样,super也不能出现static方法中。 static是一个特殊的关键字,它可以用于修饰方法、成员变量等成员。static修饰的成员表明成它属于这个类本身,而不属于该类的单个实例,因此通常把static修饰的成员变量和方法称为类变量和类方法。不使用static修饰的普通方法、成员变量则属于该类的单个实例,而不属于该类,通常将其称为实例方法、实例变量(非静态方法、非静态变量)。

2、 实例变量
如果子类定义了和父类同名的实例变量,则会发生子类实例变量隐藏父类实例变量的情形。在正常情况下,子类里定义的方法直接访问该 实例变量默认会访问到子类中定义的实例变量,可以通过super来访问父类中被隐藏的实例变量,如下代码所示。

class fatherClass
{
public int a = 5;
}
public class sonClass extends fatherClass
{

public int a = 7;
public void accessSon()
{
System.out.println(a); //7
}
public void accessFther()
{
//通过super来访问从父类继承得到的a实例变量
System.out.println(super.a); //5
}
}

如果被覆盖的是类变量,在子类的方法中则可以通过父类名作为调用者来访问被覆盖的类变量。

提示:当程序创建一个子类对象时,系统不仅会为该类中定义的实例变量分配内存,也会为它从父类继承得到的所有实例变量分配内存,即使子类定义了与父类中同名的实例变量,也就是说,当系统创建一个java对象时,如果该java类有两个父类(一个直接父类A,一个间接父类B),假设A类中定义了2个实例变量,B中定义了3个实例变量,当前类中定义了2个实例变量,那么这个java对象将会保存2+3+2个实例变量。

3、 构造器
如果在构造器中使用super,则super用于限定该构造器初始化的是该对象从父类继承得到的实例变量,而不是该类自身定义的实例变量。
在一个构造器中调用另一个重载的构造器使用this调用来完成,在子类构造器中调用父类构造器,用super调用来完成。

class Base
{
public double size;
public String name;
public Base(double size, String name)
{
this.size=size;
this.name=name;
}
}
public class Sub extends Base
{

public String color;
public Sub(double size, String name, String color)
{
//使用super来调用父类构造器的初始化过程
super(size, name);
this.color=color;
}
}

使用super调用和使用this调用的区别在于super调用的是父类的构造器,而this调用的是同一个类中重载的构造器。因此,使用super调用父类构造器也必须出现在子类构造器执行体的第一行,this调用和super调用不会同时出现。

注意:创建任何对象总是从该类所在继承树最顶层类的构造器开始执行,然后依次向下执行,最后才执行本类的构造器。如果父类通过this调用了同类中重载的构造器,就会一次执行父类的多个构造器。