从技术上说,构造方法是不能被覆盖的。由于它们的名称总是与当前类相同,构造函数是新创建的,而不是继承而来的。在很多时候,这样做是没有问题的;当类的构造方法被调用时,所有超类中特征标与此相同的构造方法也将被调用。因此,类中所有继承而来的部分都将被初始化。
然而,为类定义构造方法时,可能想修改对象的初始化方式,不但初始化类中新增的变量,而且要修改继承而来的变量的内容。为此,可以显式地调用超类的构造方法,并修改需要修改的变量。
要调用超类中的常规方法,可以使用super.methodname(arguments)。由于构造方法没有可供调用的方法名,因此采用如下格式:
super(arg1,arg2,arg3,…);
注意,Java对super()的用法有特殊的规则:它必须是构造函数定义中的第一条语句。如果构造函数没有显式地调用super(),Java将自动调用:使用不带参数的super()。由于对方法super()的调用必须是第一条语句,因此在覆盖构造函数中,不能像下面这样做:
if (condition == true)
super(1,2,3);
else
super(1,2);
与在构造方法中使用this()类似,super()将调用直接超类的构造方法(这可能会调用其超类的构造函数,依此类推)。注意,要使super()调用管用,超类中必须有特征标与此相同的构造函数。在编译源文件时,Java编译器会检查这一点。
不必调用超类中特征标与子类的构造函数相同的构造函数,而只需要为需要初始化的值调用构造函数。实际上,可以创建一个这样的类,即它的构造函数的特征标与任何超类的构造函数都完全不同。
以下程序是一个名为NamedPoint的类,它是从java.awt包中的Point类派生而来的。Point类只有一个构造函数,该构造函数接受x和y坐标作为参数,并返回一个Point对象。NamedPoint新增了一个实例变量(一个表示名称的字符串),并定义了一个用于初始化x、y和名称的构造函数。
Import java.awt.Point;
clsss NamedPoint extends Point{
String name;
NamePoint(int x,int y,String name){
Super(x,y);
This.name = name;
}
Public static void main(String[] arguments){
NamedPoint np = new NamedPoint(5,5,”SmallPoint”);
System.out.println(“x is” + np.x);
System.out.println(“y is” + np.y);
System.out.println(“Name is” + np.name);
}
}
该程序的输出如下:
x is 5
y is 5
Name is SmallPoint
NamePoint的该构造方法调用Point的构造方法来初始化Point的实例变量(x和y)。虽然自己初始化x和y也很容易,但可能不知道Point在初始化自身时还执行了哪些操作。因此,比较好的办法是将构造方法沿类层次结构向上传递,以确保一切都被正确地设置。