从之前的文章中分享过的一些知识,从Box派生的类并没有体现出它们的实际上是多么有效和强大。例如,BoxWeight构造函数明确的初始化了Box( )的width、height和depth成员。
这些重复的代码在它的超类中已经存在,这样做效率很低,而且,这意味着子类必须被同意具有访问这些成员的权力。然而,有时你希望创建一个超类,该超类可以保持它自己实现的细节(也就是说,它保持私有的数据成员)。这种情况下,子类没有办法直接访问或初始化它自己的这些变量。既然封装是面向对象的基本属性,Java提供了该问题的解决方案是不值得奇怪的。
任何时候一个子类需要引用它直接的超类,它可以用关键字super来实现。super有两种通用形式。第一种调用超类的构造函数。第二种用来访问被子类的成员隐藏的超类成员。下面分别介绍每一种用法(第二种下个文章中介绍)。
使用super调用超类构造函数
子类可以调用超类中定义的构造函数方法,用super的下面形式:
super(parameter-list);
这里,parameter-list定义了超类中构造函数所用到的所有参数。super( )必须是在子类构造函数中的第一个执行语句。为了了解怎样运用super( ),考虑下面BoxWeight( )的改进版本:
// BoxWeight now uses super to initialize its Box attributes.
class BoxWeight extends Box {
double weight; // weight of box
// initialize width, height, and depth using super()
BoxWeight(double w, double h, double d, double m) {
super(w, h, d); // call superclass constructor
weight = m;
}
}
这里,BoxWeight( )调用带w、h和d参数的super( )方法。这使Box( )构造函数被调用,用w、h和d来初始化width, height, 和 depth。BoxWeight不再自己初始化这些值。它只需初始化它自己的特殊值:weight。这种方法使Box可以自由的根据需要把这些值声明成private。
上面的例子,调用super( )用了三个参数。既然构造函数可以被重载,可以用超类定义的任何形式调用super( ),执行的构造函数将是与所传参数相匹配的那一个。
例如,下面是BoxWeight一个完整的实现,BoxWeight具有以不同方法构造盒子的构造函数。在每种情况下,用适当的参数调用super( )。注意width, height, and depth在Box是私有的。
// A complete implementation of BoxWeight.
class Box {
private double width;
private double height;
private double depth;
// construct clone of an object
Box(Box ob) {
// pass object to constructor
width = ob.width;
height = ob.height;
depth = ob.depth