До сих пор мы использовали простые иерархии классов, которые состояли
только из суперкласса и подкласса. Однако можно строить иерархии, которые содержат любое количество уровней наследования.
Скачать исходники для статьи можно ниже
Как уже отмечалось, вполне допустимо использовать подкласс в качестве суперкласса другого подкласса.
Например, класс С может быть подклассом класса В, который, в свою очередь, является подклассом класса А.
В подобных ситуациях каждый подкласс наследует все характеристики всех его суперклассов.
В приведенном примере класс С наследует все характеристики классов В и А.
В качестве примера многоуровневой иерархии рассмотрим следующую программу. В ней подкласс BoxWeight использован в качестве суперкласса для создания подкласса Shipment. Класс Shipment наследует
все характеристики классов BoxWeight и Box, а также добавляет поле cost, которое содержит стоимость поставки такого пакета.
// Расширение класса BoxWeight за счет включения в него
// стоимости доставки.
// Начнем с создания класса Box.
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; // значение -1 используется для указания
height = -1; // неинициализированного
depth = -1; // параллелепипеда
}
// конструктор, используемый при создании куба
Box(double len) {
width = height = depth = len;
}
// вычисление и возврат объема
double volume() {
return width * height * depth;
}
}
// Добавление веса.
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 Shipment extends BoxWeight {
double cost;
// конструирование клона объекта
Shipment(Shipment ob) { // передача объекта конструктору
super(ob);
cost = ob.cost;
}
// конструктор, используемый при указании всех параметров
Shipment(double w, double h, double d, double m, double c){
super(w, h, d, m); // вызов конструктора суперкласса
cost = с;
}
// конструктор, используемый по умолчанию
Shipment() {
super();
cost = -1;
}
// конструктор, используемый при создании куба
Shipment(double len, double m, double c) {
super(len, m);
cost = c;
}
}
class DemoShipment {
public static void main(String args[]) {
Shipment shipment1 = new Shipment(10, 20, 15, 10, 3.41);
Shipment shipment2 = new Shipment(2, 3, 4, 0.76, 1.28);
double vol;
vol = shipment1.volume();
System.out.println("Объем shipmentl равен " + vol);
System.out.println("Bec shipmentl равен " + shipment1.weight);
System.out.println("Стоимость доставки: $" + shipment1.cost);
System.out.println();
vol = shipment2.volume();
System.out.println("Объем shipment2 равен " + vol);
System.out.println("Bec shipment2 равен " + shipment2.weight);
System.out.println("Стоимость доставки: $" + shipment2.cost);
}
}
Вывод этой программы будет следующим:
Объем shipment1 равен 3000.0
Вес shipmentl равен 10.0
Стоимость доставки: $3.41
Объем shipment2 равен 24.0
Вес shipment2 равен 0.76
Стоимость доставки: $1.28
Благодаря наследованию, класс Shipment может использовать ранее определенные классы Box и BoxWeight, добавляя только ту дополнительную информацию, которая требуется для его собственного специализированного применения.
В этом состоит одно из ценных свойств наследования. Оно позволяет повторно использовать код.
Приведенный пример иллюстрирует важный аспект: метод super() всегда
ссылается на конструктор ближайшего суперкласса в иерархии.
Метод super() в классе Shipment вызывает конструктор класса BoxWeight. Метод super() в классе BoxWeight вызывает конструктор класса Box.
Если в иерархии классов конструктор суперкласса требует передачи ему параметров, все подклассы должны передавать эти параметры “по эстафете”. Данное утверждение справедливо независимо от того, нуждается ли подкласс в собственных параметрах.


