怎么用super调用超类构造函数?

2024-07-02 11:49:07 浏览数 (1)

从Box派生的类并没有体现出它们的实际上是多么有效和强大。例如,BoxWeight构造函数明确的初始化了Box( )的width、height和depth成员。

这些重复的代码在它的超类中已经存在,这样做效率很低,而且,这意味着子类必须被同意具有访问这些成员的权力。然而,有时你希望创建一个超类,该超类可以保持它自己实现的细节(也就是说,它保持私有的数据成员)。这种情况下,子类没有办法直接访问或初始化它自己的这些变量。既然封装是面向对象的基本属性,Java提供了该问题的解决方案是不值得奇怪的。

任何时候一个子类需要引用它直接的超类,它可以用关键字super来实现。super有两种通用形式。第一种调用超类的构造函数。第二种用来访问被子类的成员隐藏的超类成员。下面分别介绍每一种用法(第二种下个文章中介绍)。

使用super调用超类构造函数 子类可以调用超类中定义的构造函数方法,用super的下面形式:

代码语言:javascript复制
java复制代码super(parameter-list); 

这里,parameter-list定义了超类中构造函数所用到的所有参数。super( )必须是在子类构造函数中的第一个执行语句。为了了解怎样运用super( ),考虑下面BoxWeight( )的改进版本:

代码语言:javascript复制
java复制代码// 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是私有的。

代码语言:javascript复制
java复制代码// 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; 
 } 
 // constructor used when all dimensions specified 
 Box(double w, double h, double d) { 
 width = w; 
 height = h; 
 depth = d; 
 } 
 // constructor used when no dimensions specified 
 Box() { 
 width = -1; // use -1 to indicate 
 height = -1; // an uninitialized 
 depth = -1; // box 
 } 
 // constructor used when cube is created 
 Box(double len) { 
 width = height = depth = len; 
 } 
 // compute and return volume 
 double volume() { 
 return width * height * depth; 
 } 
} 
// BoxWeight now fully implements all constructors. 
class BoxWeight extends Box { 
 double weight; // weight of box 
 // construct clone of an object 
 BoxWeight(BoxWeight ob) { // pass object to constructor 
 super(ob); 
 weight = ob.weight; 
 } 
 // constructor when all parameters are specified 
 BoxWeight(double w, double h, double d, double m) { 
 super(w, h, d); // call superclass constructor 
 weight = m; 
 } 
 // default constructor 
 BoxWeight() { 
 super(); 
 weight = -1; 
 } 
 // constructor used when cube is created 
 BoxWeight(double len, double m) { 
 super(len); 
 weight = m; 
 } 
} 
class DemoSuper { 
 public static void main(String args[]) { 
 BoxWeight mybox1 = new BoxWeight(10, 20, 15, 34.3); 
 BoxWeight mybox2 = new BoxWeight(2, 3, 4, 0.076); 
 BoxWeight mybox3 = new BoxWeight(); // default 
 BoxWeight mycube = new BoxWeight(3, 2); 
 BoxWeight myclone = new BoxWeight(mybox1); 
 double vol; 
 vol = mybox1.volume(); 
 System.out.println("Volume of mybox1 is "   vol); 
 System.out.println("Weight of mybox1 is "   mybox1.weight); 
 System.out.println(); 
 vol = mybox2.volume(); 
 System.out.println("Volume of mybox2 is "   vol); 
 System.out.println("Weight of mybox2 is "   mybox2.weight); 
 System.out.println(); 
 vol = mybox3.volume(); 
 System.out.println("Volume of mybox3 is "   vol); 
 System.out.println("Weight of mybox3 is "   mybox3.weight); 
 System.out.println(); 
 vol = myclone.volume(); 
 System.out.println("Volume of myclone is "   vol); 
 System.out.println("Weight of myclone is "   myclone.weight); 
 System.out.println(); 
 vol = mycube.volume(); 
 System.out.println("Volume of mycube is "   vol); 
 System.out.println("Weight of mycube is "   mycube.weight); 
 System.out.println(); 
 } 
}

该程序产生下面的输出:

代码语言:javascript复制
java复制代码Volume of mybox1 is 3000.0 
Weight of mybox1 is 34.3 
Volume of mybox2 is 24.0 
Weight of mybox2 is 0.076 
Volume of mybox3 is -1.0 
Weight of mybox3 is -1.0 
Volume of myclone is 3000.0 
Weight of myclone is 34.3 
Volume of mycube is 27.0 
Weight of mycube is 2.0 

特别注意BoxWeight( )中的这个构造函数:

代码语言:javascript复制
java复制代码// construct clone of an object 
BoxWeight(BoxWeight ob) { // pass object to constructor 
 super(ob); 
 weight = ob.weight; 
} 

注意super( )被用一个BoxWeight类型而不是Box类型的对象调用。这仍然调用了构造函数Box(Box ob)。前面已经提醒过,一个超类变量可以引用作为任何一个从它派生的对象。

因此,我们可以传递一个BoxWeight对象给Box构造函数。当然,Box只知道它自己成员的信息。

让我们复习super( )中的关键概念。当一个子类调用super( ),它调用它的直接超类的构造函数。这样,super( )总是引用调用类直接的超类。这甚至在多层次结构中也是成立的。

还有,super( )必须是子类构造函数中的第一个执行语句。

0 人点赞