如果需要在子类方法中调用父类被覆盖的实例方法,则可使用super限定来调用父类被覆盖的实例方法。
super是java提供的一个关键字,super用于限定该对象调用它从父类继承得到的实例变量或方法。正如this不能出现在static修饰的方法中一样,super也不能出现在static修饰的方法中。static修饰的方法是属于类的,该方法的调用者可能是一个类,而不是对象,因而super限定也就失去了意义。
如果子类定义了和父类同名的实例变量,则会发生子类实例变量隐藏父类实例变量的情形。在正常情况下,子类里定义的方法直接访问该实例变量默认会访问到子类中定义的实例变量,无法访问到父类中被隐藏的实例变量。在子类定义的实例方法中可以通过super来访问父类中被隐藏的实例变量,代码如下所示。
class BaseClass
{
public int a=5;
}
public class SubClass extends BaseClass
{
public int a=7;
public void accessOwner()
{
System.out.println(a);
}
public void accessBase()
{
//通过super来限定访问从父类继承得到的a实例变量
System.out.println(super.a);
}
public static void main(String[] args)
{
SubClass sc=new SubClass();
sc.accessOwner(); //输出7
sc.accessBase(); //输出5
}
}
上面程序的BaseClass和SubClass中都定义了名为a的实例变量,则SubClass的a实例变量将会隐藏BaseClass的a实例变量。当系统创建了SubClass对象时,实际上会为SubClass对象分配两块内存,一块用于存储在SubClass类中定义的a实例变量,一块用于存储从BaseClass类继承得到的a实例变量。
程序中粗体字代码访问super.a时,此时使用super限定访问该实例从父类继承得到的a实例变量,而不是在当前类中定义的a实例变量。
如果子类里没有包含和父类同名的成员变量,那么在子类实例方法中访问该成员变量时则无须显示使用super或父类名作为调用者。如果在某个方法中访问名为a的成员变量,但没有显示指定调用者,则系统查找a的顺序为:
1.查找该方法中是否有名为a的局部变量
2.查找当前类中是否包含名为a的成员变量
3.查找a的直接父类中是否包含名为a的成员变量,依次上溯a的所有父类,直到java.lang.Object类,如果最终不能找到名为a的成员变量,则系统出现编译错误。
如果被覆盖的是类变量,在子类的方法中则可以通过父类名作为调用者来访问被覆盖的类变量。