Читайте также: |
|
}.
Этот класс - наследник класса TTelemetryDatas (об этом говорится в первой строке описания класса с помощью выражения :public TTelemetryDatas. Класс TElectricalDatas наследует (включает) все содержимое класса-предка TTelemetryDatas, но исходная структура дополнена конструктором TElectricalDatas, деструктором ~ TElectricalDatas, четырьмя новыми элементами, а поведение - переопределено (изменена функция transmit). Кроме того, добавлена функция currentPower (текущее напряжение).
Таким образом, с учетом содержимого класса-предка TTelemetryDatas транслятор преобразует исходное описание класса TElectricalDatas к следующему виду:
class TElectricalDatas: public TTelemetryDatas
{
public:
TTelemetryDatas(); // конструктор унаследован
virtual ~TTelemetryDatas(); // деструкторунаследован
TTime currentTime(); // метод унаследован
protected:
int intIdent; // поле унаследовано
TTime timStamp; // поле унаследовано
public:
TElectricalDatas(); // конструктор введен
~ TElectricalDatas(); // деструктор введен
virtual void transmit(); // одноименный метод переопределен
double currentPower(); // метод введен
protected:
double dubFuelCell1Voltage(); // метод введен
double dubFuelCell2Voltage(); // метод введен
double dubFuelCell1Amperes(); // метод введен
double dubFuelCell2Amperes(); // метод введен
}.
Попросту говоря, наследование - это такое отношение между классами, когда один класс повторяет структуру и поведение другого класса (одиночное наследование) или других (множественное наследование) классов. Класс, структура и поведение которого наследуются, называется суперклассом. Так, TTelemetryDatas является суперклассом для TElectricalDatas. Производный от суперкласса класс называется подклассом. Это означает, что наследование устанавливает между классами иерархию общего и частного. В этом смысле TElectricalDatas является более специализированным классом более общего TTelemetryDatas. Мы уже видели, что в подклассе структура и поведение исходного суперкласса дополняются и переопределяются. Наличие механизма наследования является отличительной чертой объектно-ориентированных языков.
Одиночное наследование. Подкласс обычно расширяет или ограничивает существующую структуру и поведение своего суперкласса. Например, подкласс TGuardedQueues («бдительная» очередь) может добавлять к поведению суперкласса TQueues (очередь) операции, которые защищают состояние очереди от одновременного изменения несколькими независимыми потоками. Обратный пример: подкласс TUnselectableDisplayItems может ограничить поведение своего суперкласса TDisplayItems, запретив выделение объекта на экране. Часто подклассы делают и то, и другое, т.е. расширяют и ограничивают родительский класс одновременно.
Отношения одиночного наследования от суперкласса TTelemetryDatas показаны на рис. 1.3. Стрелки обозначают отношения частного к общему. Например, TCameraDatas - это разновидность класса TSensorDatas, который в свою очередь является разновидностью класса TTelemetryDatas. В главе 3 мы покажем, что правильная организация иерархии абстракций - это вопрос логической классификации.
Одиночное наследование
Рис. 1.3
Можно ожидать, что для некоторых классов на рис. 1.3 будут созданы экземпляры, а для других - нет. Наиболее вероятно образование объектов самых специализированных классов, например, TElectricalDatas и TSpectrometerDatas (такие классы называют конкретными классами, или листьями иерархического дерева). Образование объектов из классов, занимающих промежуточное положение (TSensorDatas или тем более TTelemetryDatas), менее вероятно. Классы, экземпляры которых не создаются, называются абстрактными. Ожидается, что подклассы абстрактных классов доопределят их до жизнеспособной абстракции, наполняя класс содержанием. В чем же смысл наследования? В повторном использовании! В нашем примере (рис. 1.3) содержимое класса TTelemetryDatas повторно используется во всех других классах показанной иерархии. Описание класса TTelemetryDatas, появившись однократно, будет скопировано шесть раз с помощью механизма наследования в другие классы, аналогичным образом содержимое класса TSensorDatas скопируется три раза.
Самый общий класс в иерархии классов называется базовым. В большинстве приложений базовых классов бывает несколько, и они отражают наиболее общие абстракции предметной области. На логическом уровне рассмотрения хорошо сделанная структура классов - это скорее лес из деревьев наследования, чем одна многоэтажная структура наследования с одним корнем. Но в некоторых языках программирования определен базовый класс самого верхнего уровня, который является единым суперклассом для всех остальных классов. В языке С++ эту роль играет класс TObject, который обеспечивает всех своих потомков свойством «быть классом, с помощью которого можно построить объект». Таким образом, класс TObject, являясь суперклассом для всех других классов, обеспечивает все построенные объекты обязательным набором свойств и поведением «быть объектом».
У класса обычно бывает два вида пользователей:
- экземпляры класса;
- подклассы.
Часто полезно иметь для них разные интерфейсы. В частности, мы хотим показать только внешне видимое поведение для экземпляров класса, но нам нужно открыть служебные функции и представления подклассам. Этим объясняется наличие открытой (public), защищенной (protected) и закрытой (private) частей описания класса в языке С++: разработчик может четко разделить, какие элементы класса доступны для экземпляров, а какие для подклассов.
Есть серьезные противоречия между потребностями наследования и инкапсуляции. В значительной мере наследование открывает наследующему классу некоторые секреты. На практике, чтобы понять, как работает какой-то класс, часто надо изучить все его суперклассы.
Наследование подразумевает, что подклассы повторяют структуры их суперклассов. В предыдущем примере экземпляры класса TElectricalDatas содержат элементы структуры суперкласса (intIdent и timStamp) и более специализированные элементы (dubFuelCell1Voltage, dubFuelCell2Voltage, dubFuelCell1Amperes, dubFuelCell2Amperes – напряжение и ток в двух топливных камерах).
Поведение суперклассов также наследуется. Применительно к объектам класса TElectricalData можно использовать операции currentTime (унаследована от суперкласса), currentPower (определена в классе) и transmit (переопределена в подклассе). В большинстве языков программирования допускается не только наследование методов суперкласса, но также добавление новых и переопределение существующих методов. В С++ любой метод суперкласса можно переопределить в подклассе.
Метод, объявленный виртуальным (функция transmit в предыдущем примере), может быть в подклассе переопределен, а остальные (currentTime) - нет[5].
Одиночный полиморфизм. Пусть процедура transmit класса TTelemetryDatas реализована следующим образом:
void TTelemetryDatas::transmit()
{
Дата добавления: 2015-10-29; просмотров: 88 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Отношения между классами | | | TransmitAmperes(); |