10239

Наследование и защищенные элементы класса

Лекция

Информатика, кибернетика и программирование

Лекция 13. Наследование и защищенные элементы класса. 13.1. Наследование. Цель объектно-ориентированного программирования состоит в повторном использовании созданных классов. Если уже создан некоторый класс то возможны ситуации что новому классу нужны многие

Русский

2013-03-24

79.5 KB

3 чел.

Лекция 13. Наследование и защищенные элементы класса.

   13.1. Наследование.

  Цель объектно-ориентированного программирования состоит в повторном использовании созданных классов. Если уже создан некоторый класс, то возможны ситуации, что новому классу нужны многие особенности уже существующего класса, и необходимо добавить один или несколько элементов данных или функций. C++ позволяет строить новый объект, используя характеристики уже существующего объекта. Новый объект будет наследовать элементы существующего класса (называемого базовым классом). Когда строится новый класс из существующего, этот новый класс называется производным классом.
  В дополнение к общим (
public) (доступным всем) и частным (private) (доступным методам класса) элементам C++ предоставляет защищенные (protected) элементы, которые доступны базовому и производному классам.
  
Наследование представляет собой способность производного класса наследовать характеристики существующего базового класса. Предположим, что есть базовый класс employee:

  class employee

   {

   public:

      employee(char *, char *, float);

      void show_employee(void);

   private:

      char name[64];

      char position[64];

      float salary;

   }; 

  Предположим, что программе требуется класс manager, который добавляет следующие элементы данных в класс employee:
          float annual_bonus;
         char company_car[64];
         int stock_options;


  Программа может выбрать два варианта:

- создать новый класс manager, который дублирует многие элементы класса employee,

- породить класс типа manager из базового класса employee.

  Порождая класс manager из существующего класса employee, снижается объем требуемого программирования и исключается дублирование кода

внутри программы.

  Для определения этого класса необходимо указать ключевое слово
class, имя manager, следующее за ним двоеточие и имя employee:
        class manager:public employee

           {

                 определяются элементы
            };
  Ключевое слово public, которое предваряет имя класса employee, указывает, что общие (public) элементы класса employee также являются общими и в классе manager. Следующие операторы порождают класс manager.
       class manager : public employee
         {
           public:
             manager(char *, char *, char *, float, float, int);
             void show_manager(void);
         private:
            float annual_bonus;
           char company_car[64];
          int stock_options;
        };

  Когда порождается класс из базового класса, частные элементы базового класса доступны производному классу только через интерфейсные функции базового класса. Таким образом, производный класс не может напрямую обратиться к частным элементам базового класса, используя оператор точку.
  Следующая программа использует наследования в C++ , создавая класс
manager из базового класса employee:

 Primer 1 Лекция 13.

#include <iostream>

#include <string.h>

using namespace std;

  class employee

  {

  public:

     employee(char *, char *, float);

     void show_employee(void);

  private:

     char name [ 64 ];

     char position[64];

     float salary;

  };

  employee::employee(char *name, char *position,float salary)

  {

     strcpy(employee::name, name);

     strcpy(employee::position, position);

     employee::salary = salary;

  }

  void employee::show_employee(void)

  {

     cout << "Имя: " << name << endl;

     cout << "Должность: " << position << endl;

     cout << "Оклад: $" << salary << endl;

  }

  class manager : public employee

  {

  public:

     manager(char *, char *, char *, float, float, int);

     void show_manager(void);

  private:

     float annual_bonus;

     char company_car[64];

     int stock_options;

  };

  manager::manager(char *name, char *position, char *company_car, float salary, float bonus, int stock_options) : employee(name, position, salary)

  {

     strcpy(manager::company_car, company_car);

     manager::annual_bonus = bonus;

     manager::stock_options = stock_options;

  }

  void manager::show_manager(void)

  {

     show_employee();

     cout << "Машина фирмы: " << company_car << endl;

     cout << "Ежегодная премия: $" << annual_bonus << endl;

     cout << "Фондовый опцион: " << stock_options << endl;

  }

  int main()

  {   

     system("chcp 1251");

     employee worker("Савин", "Программист", 35000);

     manager boss("Нагель", "Вице-президент", "Ford", 50000.0, 5000, 1000);

     worker.show_employee();

     boss.show_manager();

     system("pause");

  }

  Программа определяет базовый класс employee,  затем определяет производный класс manager. Обратите внимание на конструктор manager. Когда порождается класс из базового класса, конструктор производного класса должен вызвать конструктор базового класса. Чтобы вызвать конструктор базового класса, необходимо поместить двоеточие после конструктора производного класса, а затем указать имя конструктора базового класса с требуемыми параметрами:

manager::manager(char *name, char *position, char *company_car, float salary, float bonus, int stock_options) :

   employee(name, position, salary)  // Конструктор базового класса

   {

   strcpy(manager::company_car, company_car);

   manager::annual_bonus = bonus;

   manager::stock_options = stock_options;

   }

  Функция show_manager вызывает функцию show_employee, которая является элементом класса employee. Поскольку класс manager является производным класса employee, класс manager может обращаться к общим элементам класса employee, как если бы все эти элементы были определены

внутри класса manager.
  Наследование представляет собой способность производного класса наследовать характеристики существующего базового класса. Если есть класс, чьи элементы данных или функции-элементы могут быть использованы новым классом, можно  построить новый класс в терминах существующего (базового) класса. Новый класс будет наследовать элементы (характеристики) существующего класса. Использование наследования для построения новых классов сэкономит значительное время. Объектно-ориентированное программирование широко использует наследование, позволяя программе строить сложные объекты из небольших легко управляемых объектов.
  Предположим, что используется базовый класс
book внутри существующей программы:

   class book

   {

   public:

      book (char *, char *, int);

      void show_book(void);

   private:

      char title[64];

      char author[б 4];

      int pages;

   }; 

 Предположим, что программе требуется создать класс library_card, который будет добавлять следующие элементы данных в класс book: 

    char catalog[64];

    int checked_out;    // 1, если проверена, иначе 0

  Программа может использовать наследование, чтобы породить класс library _card из класса book:

     class library_card : public book

      {

        public:

          library_card(char *, char *, int, char *, int);

         void show_card(void);

        private:

         char catalog[64];

        int checked_out;

       }

Следующая программа порождает класс library_card из клacca book:

Primer 1 Лекция 13.

#include <iostream>

#include <string.h>

using namespace std;

  class book

  {

  public:

     book(char *, char *, int);

     int show_book();

  private:

     char title [64];

     char author[64];

     int pages;

   };

  book::book(char *title, char *author, int pages)

  {

     strcpy(book::title, title);

     strcpy(book::author, author);

     book::pages = pages;

   }

  int book::show_book()

  {

     cout << "Название: " << title << endl;

     cout << "Автор: " << author << endl;

     cout << "Страниц: " << pages << endl;

  }

  class library_card : public book

  {

  public:

     library_card(char *, char *, int, char *, int);

     int show_card();

  private:

     char catalog[64];

     int checked_out;

  };

  library_card::library_card(char *title, char *author, int pages, char *catalog, int checked_out) : book(title, author, pages)

  {

     strcpy(library_card::catalog, catalog);

     library_card::checked_out = checked_out;

  }

  int library_card::show_card()

  {

     show_book();

     cout << "Каталог: " << catalog << endl;

     if (checked_out) cout << "Статус: проверена" << endl;

     else cout << "Статус: свободна" << endl;

   }

   int main()

  {   

     system("chcp 1251");

     library_card card( "C++", "Подбельский", 272, "101СРР", 1);

     card.show_card();

     system("pause");

  }

  Конструктор library _card вызывает конструктор класса book для инициализации элементов класса book. Использование функции-элемента show_book класса book внутри функции show_card. Поскольку класс library_card наследует методы класса book, функция show_card может вызвать этот метод (show_book) без помощи оператора точки, как если бы этот метод был методом класса library_card.

   13.2. Защищенные элементы.

  При изучении определений базовых классов можно встретить элементы, объявленные как public, private и protected (общие, частные и защищенные). Производный класс может обращаться к общим элементам базового класса, как будто они определены в производном классе. Производный класс не может обращаться к частным элементам базового класса напрямую. Для обращения к таким элементам производный класс использует интерфейсные функции. Защищенные элементы базового класса занимают промежуточное положение между частными и общими. Если элемент является защищенным, объекты производного класса могут обращаться к нему, как будто он является общим. Для оставшейся части программы защищенные элементы являются как бы частными. Единственный способ, с помощью которого программы могут обращаться к защищенным элементам, состоит в использовании интерфейсных функций. Следующее определение класса book использует метку protected, чтобы позволить классам, производным от класса book, обращаться к элементам title, author и pages напрямую, используя оператор точку:

class book

{

   public:

     book(char *, char *, int);

     void show_book(void);

  protected:

      char title [64];

     char author[64];

     int pages;

};

  Если предполагается, что через некоторое время придется породить новые классы из создаваемого класса, установите, должны ли будущие производные классы напрямую обращаться к определенным элементам создаваемого класса, и объявите такие элементы защищенными, а не частными.
  Производный класс может обращаться
к защищенным элементам базового класса напрямую, используя оператор точку. Однако оставшаяся часть программы может обращаться к защищенным элементам только с помощью интерфейсных функций этого класса. Таким образом, защищенные элементы класса находятся между общими (доступными всей программе) и частными (доступными только самому классу) элементами.
  Если порождается один класс из другого, возможны ситуации, когда имя элемента класса в производном классе является таким же, как имя элемента в базовом классе. Если возник такой конфликт, C++ всегда использует элементы производного класса внутри функций производного класса. Например, предположим, что классы book и library_card используют элемент price. В случае класса book элемент price соответствует продажной цене книги, например $22.95. В случае класса library'_card price может включать библиотечную скидку, например $18.50. Если в вашем исходном тексте не указано явно (с помощью оператора глобального разрешения), функции класса library_card будут использовать элементы производного класса {library_card). Если же функциям класса library_card необходимо обращаться к элементу price базового класса {book), они должны использовать имя класса book и оператор разрешения, например book::price. Предположим, что функции show_card необходимо вывести обе цены. Тогда она должна использовать следующие операторы:
 

cout << "Библиотечная цена: $" << price << endl;

cout << "Продажная цена: $" << book::price << endl; 

 Если в производном и базовом классе есть элементы с одинаковым именем, то внутри функций производного класса C++ будет использовать элементы производного класса. Если функциям производного класса необходимо обратиться к элементу базового класса, необходимо использовать оператор глобального разрешения:

                                base class:: member


 

А также другие работы, которые могут Вас заинтересовать

31437. Общая характеристика философии эпохи Возрождения (основные направления философской мысли, представители) 43.5 KB
  Время о котором идет речь философы Возрождения называли Новым связывая его с выработкой принципиально иных подходов к развитию искусства и науки. Эпоха Возрождения это эпоха зарождения капиталистических отношений создания национальных государств и абсолютных монархий Западной Европы эпоха глубоких социальных конфликтов. Специфика философской культуры Возрождения Философская мысль эпохи Возрождения охватывает три столетия: от раннего гуманизма XIV в.
31438. Основные черты западноевропейской философии XVII века. Философия Ф. Бэкона, Т. Гоббса, Д. Локка. Философия Р. Декарта 50 KB
  В философии на первый план выдвигаются проблемы теории познания гносеологии в частности: что значит знать что пролагает дорогу к истине ощущения или разум интуиция или логика аналитическим или синтетическим должно быть познание и т. Одна группа работ посвящена проблемам развития науки и анализа научного познания. Основной задачей философии Бэкон считал конструирование нового метода познания а целью науки принесение пользы человечеству. Фундаментом всякого познания по оценке Бэкона является опыт который должен быть...
31439. Основные черты западноевропейской философии XVIII века. Философские взгляды просветителя Ж.-Ж. Руссо. Утопический социализм Сен-Симона и Оуэна. Философия французского материализма XVIII века (Дидро, Гельвеции, Гольбах) 39 KB
  Руссо. Второй этап с середины 40х годов до конца 80х годов до Французской революции: Руссо Кондильяк и четыре великих французских материалиста Ламетри Дидро Гельвеций и Гольбах. К материалистам относятся вышеупомянутые четыре французских материалиста деистическую религию исповедовал Вольтер; новую разновидность подхода к христианству религию чувства развивал Руссо. Большинство просветителей склонялись к идеям реформизма меньшинство например Мелье Руссо были революционерами.
31440. Немецкая классическая философия: Кант, Фейербах 31 KB
  Для Канта этот вопрос сводится к вопросу о возможности чистой математики и чистого естествознания см. Кант Родоначальником немецкой классической философии стал Иммануил Кант 17241804 В философии Канта выделяется два периода:1 докритический и 2 критический. На первом этапе Кант выступает материалистом.
31441. Немецкая классическая философия: Гегель 24 KB
  Самораскрытие Абсолютного Духа в пространстве это природа; самораскрытие во времени история. Историю движут противоречия между национальными духами которые суть мысли и проекции Абсолютного Духа. Когда у Абсолютного Духа исчезнут сомнения он придёт к Абсолютной Идее Себя а история закончится и настанет Царство Свободы. Войны между народами выражают напряжённое столкновение мыслей Абсолютного Духа.
31442. Мир, природа, бытие, субстанция, материя 25.5 KB
  Философском энциклопедическом словаре имеется следующее определение: âБытие философская категория обозначающая реальность существующую объективно вне и независимо от сознания человекаâ. Самый первый философ кот изучал бытие Парменид: бытие есть не бытие нет мыслимое существует не мыслимое не существует. У Платона бытиеэто мир идей.
31443. Материя и проблема субстанции в философии. Монизм, дуализм, плюрализм. Философия и наука о материальном единстве мира как единстве многообразия сущего 36.5 KB
  Материя как субстанция обладает свойствами: несотворимость неуничтожимость бесконечность способность к саморазвитию. Материя как субстанция не существует отдельно от материальных явлений как нечто самостоятельное она существует только в них и через них. Материя объективное бытие.
31444. Материя и движение. Движение – способ существования материи. Диалектика абсолютного и относительного движения. Движение и покой 28.5 KB
  Диалектика абсолютного и относительного движения. В онтологическом смысле материя это бесконечное множество всех существующих в мире объектов и систем субстрат любых свойств связей отношений и форм движения; в мире нет ничего кроме движущейся материи . Относительность: нет просто движения движения вообще а есть только его отдельные формы ограничение его исторически и локально в пространстве. Прекращение одних форм движения замещается возникновением др.
31445. Пространство и время - формы существования материи. Развитие представлений о пространстве и времени в истории философской и научной мысли. Проблема взаимосвязи категорий «материя», «движение», «пространство» и «время». Значение теории относительности для 28.5 KB
  Развитие представлений о пространстве и времени в истории философской и научной мысли. В истории философии сложилось 2 концепции пространства и времени 1 В античности Демокрит и Эпикур. Именно матери определяет свойства пространства и времени. Свойства пространства и времени: общие и частные.