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


 

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

22068. Гуманизм и Реформация 55 KB
  Ненависть народа направлена была также и против католической церкви которая пользуясь государственной слабостью Германии старалась выкачать из нее как можно больше денег. Города и прежде всего вольные города становились важнейшими очагами духовной жизни Германии вступившей в эпоху возрождения. По той резкости с какой наиболее воинствующие гуманисты Германии нападали на алчность развращенность и обскурантизм католического клира не щадя при этом официального богословия они несомненно превосходили своих итальянских учителей. Для...
22069. Методика і техніка організації експерименту 70.5 KB
  Методика і техніка організації експерименту План 1.Етапи проведення експерименту. Види експерименту і методика їх проведення.Типові помилки в проведенні експерименту.
22070. Обробка, аналіз та інтерпретація отриманої інформації 313.5 KB
  Потім близькі за смислом відповіді обєднуються і кожній групі приписується певний код. Таким чином при класифікації відкритих відповідей необхідно дотримуватися наступних правил: виділяти групи відповідей у відповідності до мети дослідження; всі відповіді в одній групі повинні мати загальну логічну і смислову основу; різні групи повинні розрізнятися чітко по смислу. Наприклад: середній бал у групі де ознаки мають такі варіації 54. Наприклад аналіз відвідування занять студентами 2х груп в першій групі 20 студентів в другій 30...
22071. ОФОРМЛЕННЯ РЕЗУЛЬТАТІВ ТЕОРЕТИКО-ЕКСПЕРТНОГО ДОСЛІДЖЕННЯ 21.5 KB
  Загальні вимоги до оформлення науководослідної роботи. Правила оформлення науководослідної роботи. Літературне оформлення науководослідної роботи. Організація і методика науководослідницької діяльності.
22072. ДИПЛОМНА, МАГІСТЕРСЬКА РОБОТИ ЯК КВАЛІФІКАЦІЙНЕ ДОСЛІДЖЕННЯ 1.3 MB
  ТЕМА: ДИПЛОМНА МАГІСТЕРСЬКА РОБОТИ ЯК КВАЛІФІКАЦІЙНЕ ДОСЛІДЖЕННЯ План 1. Загальна характеристика дипломноїмагістерської роботи. Алгоритм написання магістерської роботи. Заключний етап роботи.
22073. НАУКОВО-ПЕДАГОГІЧНЕ ДОСЛІДЖЕННЯ 100 KB
  ТЕМА: НАУКОВОПЕДАГОГІЧНЕ ДОСЛІДЖЕННЯ План 1. Науково педагогічне дослідження: сутність мета і завдання.Види та етапи науковопедагогічного дослідження. Педагогічні дослідження: методологічні поради молодим науковцям.
22074. ТЕОРЕТИЧНИЙ ПОШУК В ПЕДАГОГІЧНОМУ ЕКСПЕРИМЕНТІ 63 KB
  Розробка задуму наукового дослідження визначення проблеми обгрунтування її актуальності; вивчення обєкту дослідження та визначення його предмету; постановка мети та формування задач дослідження.Теоретичний пошук має велике значення у визначенні сутності експериментального дослідження. Починається теоретичний пошук з розробки задуму наукового дослідження. Задум наукового дослідження це уявлення про те нове що буде привнесено в теорію і практику в результаті дослідження закономірності перебігу і розвитку процесу практичні...
22075. ЗАГАЛЬНА МЕТОДОЛОГІЯ НАУКОВОГО ДОСЛІДЖЕННЯ 239.5 KB
  ТЕМА: ЗАГАЛЬНА МЕТОДОЛОГІЯ НАУКОВОГО ДОСЛІДЖЕННЯ План 1. методика і техніка дослідження. Методологічні основи педагогічного дослідження. Педагогічні дослідження: методологічні поради молодим науковцям.
22076. МЕТОДОЛОГІЯ ТЕОРЕТИЧНОГО ДОСЛІДЖЕННЯИ 51.5 KB
  ТЕМА: МЕТОДОЛОГІЯ ТЕОРЕТИЧНОГО ДОСЛІДЖЕННЯИ План 1. Методи наукового дослідження. Особливості теоретичного дослідження 3. Характеристика методів теоретичного дослідження.