由于子类不能继承父类的构造方法,因此,要显式调用父类的构造方法,必须在子类的构造方法体的第一行使用super( )方法。该方法会调用父类相应的构造方法来完成子类对象的初始化工作。
在以下情况下需要使用super关键字:
①在类的构造方法中,通过super语句调用该类的父类的构造方法。
②在子类中访问父类中的成员。
一、用super()调用父类构造方法
(1)super()表示调用父类的构造方法
①子类继承父类,子类的构造方法的第一行,系统会默认加上super(),在调用子类的构造方法时,先调用父类的无参数构造方法。
②如果父类中只有有参数构造方法,那么子类继承父类时会报错,因为子类的构造方法在默认调用父类无参数构造方法时,找不到父类的无参数构造方法。
③如果子类的第一行编写了this(),因为this( )也会占用第一行,所以此时就会super()挤掉,就不会调用父类构造方法。
(2)实例分析
①子类的构造方法会默认在第一行先调用父类无参数构造方法super()。
//父类
public class Father{
int id;
public Father(){
System.out.println("调用父类中的构造方法");
}
}
//子类
public calss Son extends Father{
public Son(){
System.out.println("调用子类构造方法");
}
}
//测试类
public class Test{
public static void main(String[] args){
Son s = new Son();
}
}
运行结果:
调用父类中的构造方法
调用子类构造方法
说明:先调用父类无参数构造方法,再调用子类构造方法。
②父类中没有无参数构造方法。
public class Father{
int id;
//定义有参数构造方法
public Father(int id){
System. out. println( "调用父类中的构造方法");
}
}
说明:子类继承父类,因为父类中没有无参数构造方法,所以子类继承父类时会报错。
③通过在子类中调用父类有参数构造方法来避免这种错误。
public class Father{
int id;
//编写有参数构造方法覆盖无参数构造方法
public Father(int id){
System. out. println("调用父类中的构造方法");
}
}
//定义子类
public class Son extends Father{
public Son(){ //在构造方法中调用父类有参数构造方法
super(10);
System.out.println("调用子类构造方法");
}
}
//编写测试类
public class Test{
public static void main(String[] args){
Son s = new Son();
}
}
测试结果:
调用父类中的构造方法
调用子类构造方法
④也可以在构造方法中调用本类中其他构造方法,来挤掉super()调用父类中无参数构造方法。
//父类
public class Father{
int id;
//有参构造方法
public Father(int id){
System. out. println("调用父类中的构造方法");
}
}
//子类
public class Son extends Father|
//无参数构造方法
public Son(){
//手动编写调用父类有参数构造方法
super( 10);
System. out. println("调用子类构造方法");
}
//有参数构造方法
public Son(int i){
//调用本类其他构造方法,挤掉super()
this( );
System. out. println();
}
}
二、用super访问父类字段和方法
使用super访问父类中的成员与this 关键字的使用相似,只不过它引用的是子类的父类,基本形式如下:
super. member
其中, member是父类中的方法或属性名称。这种形式多用于子类的成员名隐藏了父类中的同名成员的情况。
案例Example6-1:在Animal 类和Cat类中分别定义了public 类型的name属性和private类型的name 属性,并且Cat类继承Animal类。那么,我们可以在Cat类中通过super关键字来访问父类Animal 中的name属性,通过this关键字来访问本类中的name属性,如下面的代码:
//父类Animal 的定义
public class Animal{
public String name; //动物名字
}
//子类Cat 的定义
public class Cat extends Animal{
private String name; //名字
public Cat(String aname, String dname)
super. name=aname; //通过super关键字来访问父类中的name属性
this. name=dname; //通过this 关键字来访问本类中的name属性
}
public String toString()
return"我是"+super. name+",我的名字叫"+this. name;
}
public static void main(String[]args)
Animal cat=new Cat("动物","喵星人");
System. out. println(cat);
}
}
运行程序,输出结果如下:
我是动物,我的名字叫喵星人
上述代码演示了使用super实现子类调用父类中同名成员的情况。尽管Cat类中的属性name隐藏了Animal 类中的name属性,但是super 允许访问父类中的name 属性。另外, super还可以用于调用被子类隐藏的方法。
三、关键字 super 和 this 的比较
①this关键字代表本类对象, super关键字代表父类对象。
②使用this.的方式可以访问本类的成员方法和成员变量,使用super.的方式可以访问父类的成员方法和成员变量。
③使用this( )的方式在构造方法的第一行表示调用本类的构造方法,使用super()的方式在构造方法的第一行表示调用父类的构造方法。