ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++ (4-Е ИЗДАНИЕ) (часть 9) онлайн

Уровни наследования

Производные классы могут являться базовыми классами для других произ- водных классов. Рассмотрим маленькую программу в качестве примера такого случая.

 

class A { };

class В : public A

{  };

class C : public В { };

Здесь класс В является производным класса A, а класс C является производ- ным класса B, Процесс может продолжаться бесконечно — класс D может быть производным класса C и т. д.

Рассмотрим более конкретный пример. Предположим, что мы решили доба- вить бригадиров в программу EMPLOY. Мы создадим новую программу, вклю- чающую в себя объекты класса foreman.

Класс foreman будет производным класса laborer. Это показано на рис. 9.8.

Рис. 9.8. UML диаграмма классов программы EMPLOY2

Бригадир наблюдает за выполнением работ, контролируя группу рабочих, и отвечает за выполнение нормы выработки своей группой. Эффективность ра- боты бригадира измеряется в процентах выполнения нормы выработки. Поле quotas класса foreman представляет собой этот процент. Далее рассмотрим лис- тинг программы EMPLOY2:

// employ2.cpp

// несколько уровней наследования

#include <iostream>

using namespace std;

const int LEN = 80;

///////////////////////////////////////////////////////////

class employee            // некий сотрудник

{

  private:

char name[ LEN ];     // имя сотрудника

    unsigned long number; // номер сотрудника

  public:

    void getdata ( )

      {

        cout << "\n  Введите фамилию: "; cin >> name;

        cout << "  Введите номер: ";     cin >> number;

      }

    void putdata ( ) const

      {

        cout << "\n  Фамилия: " << name;

        cout << "\n  Номер: " << number;

      }

};

///////////////////////////////////////////////////////////

class manager : public employee // менеджер

{

  private:

    char title[ LEN ];          // должность, например вице-президент

    double dues;                // сумма взносов в гольф-клуб

  public:

    void getdata ( )

      {

        employee::getdata ( );

        cout << "  Введите должность: "; cin >> title;

        cout << "  Введите сумму взносов в гольф-клуб: "; cin >> dues;

      }

    void putdata ( ) const

      {

        employee::putdata ( );

        cout << "\n  Должность: " << title;

        cout << "\n  Сумма взносов в гольф-клуб: " << dues;

      }

};

///////////////////////////////////////////////////////////

class scientist : public employee // ученый

{

  private:

    int pubs;                   // количество публикаций

  public:

    void getdata ( )

      {

        employee::getdata ( );

        cout << "  Введите количество публикаций: "; cin >> pubs;

      }

    void putdata ( ) const

      {

        employee::putdata ( );

        cout << "\n  Количество публикаций: " << pubs;

      }

};

///////////////////////////////////////////////////////////

class laborer : public employee // рабочий

{

};

///////////////////////////////////////////////////////////

class foreman : public laborer // бригадир

{

  private:

    float quotas;               // норма выработки

  public:

    void getdata ( )

      {

        laborer::getdata ( );

        cout << "  Введите норму выработки: "; cin >> quotas;

      }

    void putdata ( ) const

      {

        laborer::putdata ( );

        cout << "\n  Норматив: " << quotas;

      }

};

///////////////////////////////////////////////////////////

int main ( )

{

  laborer l1;

  foreman f1;

 

  // введем информацию о нескольких сотрудниках

  cout << endl;

  cout << "\nВвод информации о первом рабочем";

  l1.getdata ( );

  cout << "\nВвод информации о первом бригадире";

  f1.getdata ( );

 

  // выведем полученную информацию на экран

  cout << endl;

  cout << "\nИнформация о первом рабочем";

  l1.putdata ( );

  cout << "\nИнформация о первом бригадире";

  f1.putdata ( );

 

  cout << endl;

  return 0;

}

 

Заметим, что иерархия классов отлична от схемы организации. На схеме организации показаны линии команд. Результатом иерархии классов является обобщение схожих характеристик. Чем более общим является класс, тем выше он находится в схеме. Таким образом, рабочий — это более общая характерис- тика, чем бригадир, который имеет определенные обязанности. Поэтому класс Laborer показан над классом foreman в иерархии классов, хотя бригадир, скорее всего, имеет большую зарплату, чем рабочий.

 

28