Бьерн Страуструп.
Язык программирования С++
317
//...
};
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;
}
Такие определения упрощают преобразование аварийного средства в обычное и наоборот:
void f(Vehicle* p)
{
delete
p->eptr;
p-
>eptr = 0; // больше нет аварийного движущегося средства
//...
p->eptr = new Emergen
cy; // оно появилось снова
}
Так какой же вариант иерархии классов лучше? В
общем случае ответ такой: "Лучшей является
Бьерн Страуструп.
Язык программирования С++
318
программа, которая наиболее непосредственно отражает реальный мир". Иными словами, при выборе
модели мы должны стремиться к большей ее"реальности", но с учетом неизбежных ограничений,
накладываемых требованиями простоты и эффективности. Поэтому, несмотря на простоту
преобразования обычного движущегося средства в аварийное, второе решение представляется
непрактичным. Пожарные машины и машины скорой помощи – это движущиеся средства специального
назначения со специально подготовленным персоналом, они действуют под управлением команд
диспетчера, требующих специального оборудования для связи. Такое положение означает, что
принадлежность к аварийным движущимся средствам - это
базовое понятие, которое для улучшения
контроля типов и применения различных программных средств должно быть прямо представлено в
программе. Если бы мы моделировали ситуацию, в которой назначение движущихся средств не столь
определенно, скажем, ситуацию, в которой частный транспорт периодически используется для доставки
специального персонала к месту происшествия, а связь обеспечивается с помощью портативных
приемников, тогда мог бы оказаться подходящим и другой
способ моделирования системы.
Для тех, кто считает пример моделирования движения транспорта экзотичным, имеет смысл сказать,
что в процессе проектирования почти постоянно возникает подобный выбор между наследованием и
принадлежностью. Аналогичный пример есть в $$12.2.5, где описывается свиток (scrollbar) -
прокручивание информации в окне.
Достарыңызбен бөлісу: