Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебник по С++.docx
Скачиваний:
1
Добавлен:
01.04.2025
Размер:
841.08 Кб
Скачать

12.2.2 Иерархии классов

Рассмотрим моделирование транспортного потока в городе, цель которого достаточно точно определить время, требующееся, чтобы аварийные движущиеся средства достигли пункта назначения. Очевидно, нам надо иметь представления легковых и грузовых машин, машин скорой помощи, всевозможных пожарных и полицейских машин, автобусов и т.п. Поскольку всякое понятие реального мира не существует изолированно, а соединено многочисленными связями с другими понятиями, возникает такое отношение как наследование. Не разобравшись в понятиях и их взаимных связях, мы не в состоянии постичь никакое отдельное понятие. Также и модель, если не отражает отношения между понятиями, не может адекватно представлять сами понятия. Итак, в нашей программе нужны классы для представления понятий, но этого недостаточно. Нам нужны способы представления отношений между классами. Наследование является мощным способом прямого представления иерархических отношений. В нашем примере, мы, по всей видимости, сочли бы аварийные средства специальными движущимися средствами и, помимо этого, выделили бы средства, представленные легковыми и грузовыми машинами. Тогда иерархия классов приобрела бы такой вид:

движущееся средство

легковая машина аварийное средство грузовая машина полицейская машина машина скорой помощи пожарная машина машина с выдвижной лестницей Здесь класс Emergency представляет всю информацию, необходимую для моделирования аварийных движущихся средств, например: аварийная машина может нарушать некоторые правила движения, она имеет приоритет на перекрестках, находится под контролем диспетчера и т.д. На С++ это можно задать так:

class Vehicle { /*...*/ };

class Emergency { /* */ };

class Car : public Vehicle { /*...*/ };

class Truck : public Vehicle { /*...*/ };

class Police_car : public Car , public Emergency {

//...

};

class Ambulance : public Car , public Emergency {

//...

};

class Fire_engine : public Truck , Emergency {

//...

};

class Hook_and_ladder : public Fire_engine {

//...

};

Наследование - это отношение самого высокого порядка, которое прямо представляется в С++ и используется преимущественно на ранних этапах проектирования. Часто возникает проблема выбора: использовать наследование для представления отношения или предпочесть ему принадлежность. Рассмотрим другое определение понятия аварийного средства: движущееся средство считается аварийным, если оно несет соответствующий световой сигнал. Это позволит упростить иерархию классов, заменив класс Emergency на член класса Vehicle:

движущееся средство (Vehicle {eptr})

легковая машина (Car) грузовая машина (Truck) полицейская машина (Police_car) машина скорой помощи (Ambulance)

пожарная машина (Fire_engine)

машина с выдвижной лестницей (Hook_and_ladder) Теперь класс Emergency используется просто как член в тех классах, которые представляют аварийные движущиеся средства:

class Emergency { /*...*/ };

class Vehicle { public: Emergency* eptr; /*...*/ };

class Car : public Vehicle { /*...*/ };

class Truck : public Vehicle { /*...*/ };

class Police_car : public Car { /*...*/ };

class Ambulance : public Car { /*...*/ };

class Fire_engine : public Truck { /*...*/ };

class Hook_and_ladder : public Fire_engine { /*...*/ };

Здесь движущееся средство считается аварийным, если Vehicle::eptr не равно нулю. "Простые" легковые и грузовые машины инициализируются Vehicle::eptr равным нулю, а для других Vehicle::eptr должно быть установлено в ненулевое значение, например:

Car::Car() // конструктор Car

{

eptr = 0;

}

Police_car::Police_car() // конструктор Police_car

{

eptr = new Emergency;

}

Такие определения упрощают преобразование аварийного средства в обычное и наоборот: