super关键字一共有两个作用:

1.父类实例的引用

2.调用父类构造器

父类实例的引用

如果需要在子类方法中调用父类被覆盖的实例方法,可使用super作为调用者来调用父类被覆盖的实例方法。

下面程序先定义了一个Hair类:

public class Hair
{
public String colour;
public static void info()
{
System.out.println("这个头发的颜色是黑色的");
}
}

复制代码

下面又定义了一个YellowHair类,这个类extends了Hair类,程序如下:

public class YellowHair extends Hair
{
public static void info()
{
System.out.println("这个头发的颜色是黄色的");
}
public void info1()
{
super.info();//也可以写成Hair.info()
}
public static void main(String[] args)
{
YellowHair a = new YellowHair();
a.info();//输出:这个头发的颜色是黄色的
a.info1();//因为引用super关键字,所以输出:这个头发的颜色是黑色的
}
}

复制代码

需要注意的是:正如this不能出现在static修饰的方法中一样,super也不能出现在static的方法中。

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

如果子类里没有包含和父类同名的属性,则子类将可以继承到父类属性。如果在子类实例方法中访问该属性时,则无形显式使用super或父类名作为调用者。因此,如果我们在某个方法中访问名为a的属性,但没有显式指定调用者,系统查找a的顺序为:

查找该方法中是否有名为a的局部变量

查找当前类中是否包含名为a的属性

查找a的直接父类中是否包含名为a的属性,依次上溯a的父类,如果没有找到,则出现编译错误

调用父类构造器

在一个构造器中调用另一个重载的构造器可以使用this调用实现,同理,在子类构造器中调用父类构造器使用super调用来实现。

public class Fruit
{
public String name;
public int weight;
public Fruit(String name,int weight)
{
this.name = name;
this.weight = weight;
}
}
public class Apple extends Fruit
{
public String colour;
public Apple(String name,int weight,String colour)
{
super(name , weight);
this.colour = colour;
}
public static void main(String[] args)
{
Aapple a = new Apple(“苹果",5,"Red");
System.out.println(a.name+" "+a.weight+" "+a.colour);
}

}复制代码

需要注意的是:

当你不加void的时候,表示你定义了一个有两个参数的构造器,Fruit(String name,int weight)。

当你加void的时候void Fruit(String name,int weight) ,就变成了类的一个方法,这时候你没有为类定义任何一个构造器,所以系统会自动你分配一个空的构造器。