Использование ключевого слова super для вызова конструкторов суперкласса

Подкласс может вызывать конструктор, определенный его суперклассом, с помощью следующей формы ключевого слова super:

super{список_аргументов);

Список_аргументов определяет любые аргументы, требуемые конструктору в суперклассе. Оператор super () всегда должен быть первым выполняемым внутри конструктора подкласса.

В качестве иллюстрации использования оператора super () рассмотрим следующую усовершенствованную версию класса BoxWeight ():

// Теперь класс BoxWeight использует ключевое слово super
// для инициализации своих атрибутов объекта Box.
class BoxWeight extends Box {
double weight; // вес параллелепипеда
// инициализация переменных width, height и depth с помощью super()
BoxWeight(double w, double h, double d, double m) {
super(w, h, d) ; // вызов конструктора суперкласса
weight = m;
}

В этом примере метод BoxWeight вызывает super () с аргументами w, h и d. Это приводит к вызову конструктора Box (), который инициализирует width, height и depth, используя переданные ему значения этих параметров. Теперь класс BoxWeight не инициализирует эти значения самостоятельно. Ему нужно инициализировать только свое уникальное значение — weight. В результате при необходимости эти значения могут оставаться приватными значениями класса Box.

В приведенном примере метод super () был вызван с тремя аргументами. Поскольку конструкторы могут быть перегруженными, super () можно вызывать, используя любую форму, определенную суперклассом. Программа выполнит тот конструктор, который соответствует указанным аргументам. В качестве примера приведем полную реализацию класса BoxWeight, которая предоставляет конструкторы для различных способов конструирования параллелепипедов. В каждом случае конструктор super () вызывается с соответствующими аргументами. Обратите внимание, что внутри класса Box его члены width, height и depth объявлены как приватные.

// Полная реализация класса BoxWeight.
class Box {
private double width;
private double height;
private double depth;
// конструирование клона объекта
Box(Box ob) {
// передача объекта конструктору
width = ob. width;
height = ob.height;
depth = ob.depth;
// конструктор, используемый при указании всех измерений
Box(double w, double h, double d) {
width = w;
height = h;
depth = d;
// конструктор, используемый, если ни одно из измерений не указано
Box () {
width = -1;
height = -1;
depth = -1;
// значение -1 используется для указания
// неинициализированного
// параллелепипеда // конструктор, используемый при создании куба
Box(double len) {
width = height = depth = len;
}
// вычисление и возврат объема
double volume () {
return width * height * depth;
}
}
// Теперь BoxWeight полностью реализует все конструкторы.
class BoxWeight extends Box {
double weight; // вес параллелепипеда
// конструирование клона объекта
BoxWeight(BoxWeight ob) {
// передача объекта конструктору
super(ob);
weight = ob.weight;
}
// конструктор, используемый при указании всех параметров
BoxWeight(double w, double h, double d, double m) {
super(w, h, d) ; // вызов конструктора суперкласса
weight = m;
}
// конструктор, используемый по умолчанию
BoxWeight() {
super ();
weight = -1;
}
// конструктор, используемый при создании куба
BoxWeight(double len, double m) {
super(len);
weight = m;
}
}
class DemoSuper {
public static void main(String args[]) {
BoxWeight myboxl = new BoxWeight(10, 20, 15, 34.3);
BoxWeight mybox2 = new BoxWeight(2, 3, 4, 0.076);
BoxWeight mybox3 = new BoxWeight ();
// по умолчанию
BoxWeight mycube = new BoxWeight (3, 2);
BoxWeight myclone = new BoxWeight(myboxl);
double vol;
vol = myboxl.volume ();
System.out.println("Объем myboxl равен " + vol) ;
System.out.println("Bee myboxl равен " + myboxl.weight);
System.out.println ();
vol = mybox2.volume();
System.out.println("Объем mybox2 равен " + vol);
System.out.println("Bee of mybox2 равен " + mybox2.weight);
System.out.println();
vol = myboxЗ.volume();
System.out.println("Объем myboxЗ равен " + vol) ;
System.out.println("Bec myboxЗ равен " + myboxЗ.weight);
System.out.println();
vol = myclone.volume();
System.out.println("Объем myclone равен " + vol);
System.out.println("Bee myclone равен " + myclone.weight);
System.out.println ();
vol = mycube.volume ();
System.out.println("Объем mycube равен " + vol);
System.out.println("Bee mycube равен " + mycube.weight);
System.out.println();
}
}

Эта программа генерирует следующий вывод:

Объем myboxl равен 3000.0
Вес myboxl равен 34.3
Объем mybox2 равен 24.0
Вес mybox2 равен 0.076
Объем myboxЗ равен -1.0
Вес myboxЗ равен -1.0
Объем myclone равен 3000.0
Вес myclone равен 34.3
Объем mycube равен 27.0
Вес mycube равен 2.0

Обратите особое внимание на следующий конструктор в классе BoxWeight:

// конструирование клона объекта
BoxWeight(BoxWeight ob) {
// передача объекта конструктору
super(ob);
weight = ob.weight;
}

Обратите внимание, что конструктор super () выполняет передачу объекту типа BoxWeight, а не типа Box. Тем не менее, это все равно ведет к вызову конструктора Box (Box. ob). Как уже было отмечено, переменную суперкласса можно использовать для ссылки на любой объект, унаследованный их этого класса. Таким образом, объект BoxWeight можно передать конструктору Box. Конечно, классу Box будут известны только его собственные члены.

Рассмотрим основные концепции применения конструктора super (). Когда подкласс вызывает конструктор super (), он вызывает конструктор своего непосредственного суперкласса. Таким образом, super () всегда ссылается на суперкласс, расположенный в иерархии непосредственно над вызывающим классом. Это положение справедливо даже в случае многоуровневой иерархии. Кроме того, оператор super () всегда должен быть первым оператором, выполняемым внутри конструктора подкласса.