Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Множественное наследование




Рассмотрим класс с именем Performer (от англ. performer – исполнитель), который вместе с Person будем использовать в качестве базового для класса Employee. Этот класс, будет содержать дополнительные данные о служащем некоторого учреждения (должность, даты начала работы и окончания работы, номер контракта, процент надбавки к базовой зарплате). Как и прежде, будем использовать отношение «является» для проверки верности этого решения. Для класса, который будет здесь спроектирован, проверочным высказыванием будет «служащий является индивидуумом и исполнителем контракта».

На рис. 3.6 представлен класс Performer, который в дальнейшем планируется использовать в качестве второго базового класса для Employee. Класс имеет уже знакомую по предыдущим примерам структуру: вначале определяются препроцессорные и статические константы, структура Date (будет использоваться для представления дат), вложенный класс Exception, закрытые, защищенные и открытые члены, три конструктора (по умолчанию, с аргументами и копирующий). Ввиду того, обработка исключений подробно рассматривалась ранее, реализация класса Exception здесь не приводится. Для хранения данных в классе Performer используются зарытые атрибуты, назначение которых пояснено в комментариях к ним. Здесь впервые используются защищенные (protected) члены класса. Напомним, что защищенные члены не доступны для пользователя класса (как закрытые члены), но доступны членам производного класса. Обратите внимание, что в этом классе хранится значение процента надбавки (атрибут PercentAdd).

 

Рис 3.6. Пример реализации класса Performer

 

В классе Person тоже есть атрибут PercentAdd и имеет такое же назначение. Такое дублирование одних и тех же данных в разных классах чаще всего говорит об ошибке проектирования. Позже мы исправим эту ошибку.

На рис. 3.7 представлен фрагмент файла Performer.cpp, содержащий реализацию основных функций класса Performer. Текст некоторых функций-членов, принцип работы которых очевиден, здесь не приводится. Обратите внимание на функцию с именем validdate, предназначенную для проверки корректности даты. При обнаружении ошибки в этой функции генерируется исключение.

 

 

Рис 3.7. Фрагмент файла Performer.cpp

 

На рис. 3.8 представлена новая версия класса Employee, который наследует два базовых класса Person и Performer, причем для последнего используется защищенное наследование. Из этого следует, что все отрытые члены класса Person будут доступны пользователю класса Employee, а открытые члены класса Performer – нет. Вся реализация класса выполнена в одном файле Employee.h. Класс имеет только один собственный атрибут с именем ID, который предназначен для хранения идентификатора служащего. В связи с тем, что этот атрибут является закрытым, для установки его значения предназначена функция-член setID. Для работы с членами базового класса Performer в классе Employee имеется несколько открытых функций, работа которых сводится к вызову функций базового класса.

 

Рис 3.8. Класс Employee, наследующий два базовых класса

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

Инкапсуляция исключений базовых классов является желательной, но это часто приводит к большому объему дополнительных работ. Альтернативой инкапсуляции в некоторой мере может служить указание спецификации исключений для функций, в которых они могут быть сгенерированы. Обратите внимание, что в заголовках функций примера на рис. 3.8 указывается список исключений. Такая запись, позволит пользователю сразу, не вникая текст функций, разобраться с механизмом обработки ошибок для данного класса. Более подробно о спецификациях исключений для функций можно прочесть в [2, 3].

Ошибка проектирования, о которой уже упоминалось выше, заставляет поддерживать два одинаковых атрибута в разных объектах. Для того, что бы некоторые переменные класса Person стали доступными в классе Emoloyee изменим для них модификатор доступа (рис.3.9), сделав его protected.

 

 

Рис 3.9. Изменение модификатора доступа для атрибутов класса Person

 

Такое изменение делает возможным в функциях-членах Employee::setAdd и Employee:set устанавливать одновременно значение атрибутов PercentAdd в двухбазовых классах. Но у пользователя все равно остается открытые члены класса Person, с помощью которых он может установить, значения этого атрибута только в объекте класса Person, что, в конечном счете приводит к противоречивости информации в классе Employee. О том, как избежать подобных ошибок будет рассказано позже.

На рис. 3.10 демонстрируется программа, использующая класс Employee. В этой программе создается объект с именем s1 класса Employee, затем с помощью отрытых методов (в том числе унаследованных от класса Person) устанавливаются значения его свойств. При создании нового объекта с именем s2 применяется копирующий конструктор. На рис. 3.11 показан результат выполнения этой программы.

 

Рис 3.10. Пример программы, использующей объекты класса Employee.

 

 

 

Рис 3.11. Результат выполнения программы на рис. 3.10

 

Как и раньше комментариями в try-блоке демонстрируются вызовы методов, приводящие к генерации исключений. Если снять комментарий с первой из этих строк, то результат обработки исключения будет похож на рис. 3.12.

 

Рис 3.12. Результат выполнения программы на рис. 3.10 в случае обработки ошибки.

 

 

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...