Пример 5. Система начисления заработной платы, использующая полиморфизм(набираем вместе)



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

Компания выплачивает служащим жалованье каждую неделю. Служащие делятся на четыре категории. Служащие с постоянной зарплатой получают фиксированную недельную плату вне зависимости от числа отработанных часов; служащие с почасовой оплатой получают почасовую ставку и сверхурочные за время, отработанное сверх 40 часов в неделю; служащие-комиссионеры получают процент от заключенных ими сделок; наконец, некоторые получают фиксированную недельную плату плюс процент со сделок. В данный момент компания решила премировать последнюю категорию служащих, выплатив им дополнительно 10% от базовой недельной платы. Компания хочет реализовать на C++ программу, которая вычисляет заработок служащих полиморфно.


 

Для представления обобщенного понятия «служащий» мы используем абстрактный класс Employee. Непосредственными производными от него являются SalariedEmployee, CommissionEmployee и HourlyEmployee. Класс Ва-

sePlusCommissionEmployee — производный от CommissionEmployee — представляет последнюю категорию служащих. Классовая диаграмма показывает иерархию наследования для нашего полиморфного приложения, начисляющего жалованье

 

Абстрактный базовый класс Employee объявляет «интерфейс» иерархии, т.е. набор элемент-функций, которые могут вызываться для всех объектов Employee. Каждый служащий, вне зависимости от способа вычисления заработка, имеет имя, фамилию и номер социального страхования, так что абстрактный базовый класс Employee имеет закрытые элементы данных firstName, lastName и socialSecurityNumber.

 

Создание абстрактного базового класса Employee

Класс Employee подробно обсуждаемый чуть ниже, в дополнение к нескольким set- и get-фуякциям для манипуляции элементами данных предусматривает функции earnings и print. Функция earnings, естественно, применима в общем смысле ко всем служащим, но конкретные вычисления зависят от класса, к которому принадлежит служащий. Поэтому мы объявляем earnings в классе Employee как чисто виртуальную, так как для этой функции реализация по умолчанию не имеет смысла — без дополнительных сведений невозможно определить, какое значение функция должна возвращать. Каждый производный класс заменяет earnings соответствующей реализацией. Чтобы вычислить заработок служащего, программа присваивает адрес его объекта указателю базового класса Employee и активирует на объекте функцию earnings. У нас имеется вектор указателей типа Employee, каждый из которых указывает на объект Employee (разумеется, объектов класса Employee не существует, поскольку это абстрактный класс, однако благодаря наследованию мы можем рассматривать все объекты любых производных от Employee классов в качестве объектов Employee). Программа проходит по вектору и вызывает earnings для каждого объекта Employee. C++ обрабатывает эти вызовы полиморфно. Включив earnings в Employee в качестве чисто виртуальной функции, мы заставляем каждый непосредственный производный от Employee класс, если он должен быть конкретным, заменять earnings. Это позволяет проектировщику классовой иерархии потребовать, чтобы каждый конкретный производный класс иерархии определял свой собственный способ расчета заработка.

Функция print в классе Employee выводит имя, фамилию и номер карточки социального страхования служащего. Как мы увидим, каждый производный класс заменяет функцию print, чтобы вывести категорию служащего (например, "salaried employee:"), за которой следует остальная информация о служащем.

Таблица  показывает слева каждый из пяти классов иерархии, а сверху — функции earnings и print. Для каждого класса показаны желаемые результаты вызова этих функций. Обратите внимание, что класс Employee специфицирует «= 0» для функции earnings, показывая, что это чисто виртуальная функция. Каждый производный класс заменяет эту функцию, предусматривая соответствующую реализацию. Мы не перечисляем в таблице set- и get-функции класса Employee, так как они не заменяются ни в одном из производных классов — эти функции наследуются каждым производным классом и используются «как они есть».


Дата добавления: 2018-08-06; просмотров: 206; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!